Skip to content

Conversation

@jjonescz
Copy link
Member

Test plan: #81207

Everything under section Existing unsafe rules of the speclet should be now handled.

@jjonescz jjonescz changed the title Unsafe evolution: require unsafe for the rest of pointer-related operations Unsafe evolution: handle the rest of pointer-related operations Nov 24, 2025
@jjonescz jjonescz marked this pull request as ready for review November 24, 2025 15:23
@jjonescz jjonescz requested a review from a team as a code owner November 24, 2025 15:23
@jjonescz jjonescz requested review from 333fred and jcouv November 24, 2025 15:24
stackAllocType = new PointerTypeSymbol(TypeWithAnnotations.Create(elementType));
break;
case ConversionKind.StackAllocToSpanType:
// Under the updated memory safety rules, a stackalloc_expression is unsafe if being converted to Span/ROS,
Copy link
Member

@333fred 333fred Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably leave a PROTOTYPE to follow up with LDM on this rule. #Resolved

expectedDiagnostics = PlatformInformation.IsWindows
? [
// error CS8911: Using a function pointer type in this context is not supported.
Diagnostic(ErrorCode.ERR_FunctionPointerTypesInAttributeNotSupported).WithLocation(1, 1),
Copy link
Member

@333fred 333fred Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this error? It doesn't appear to have a good location or span, and and I don't know why a function pointer type would be illegal here. #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the issue linked in the comment above - #77389.

It doesn't have a location because it's produced during emit inside TypeSerializer iirc, where there is no location information.

I could get rid of it by switching to portalepdb (instead of pdb on windows) but it seems there is no test for the bug, so I figured it would be good to have it captured in a test.

@jcouv jcouv self-assigned this Nov 24, 2025
@jjonescz jjonescz requested a review from 333fred November 25, 2025 13:08
expectedDiagnostics = PlatformInformation.IsWindows
? [
// error CS8911: Using a function pointer type in this context is not supported.
Diagnostic(ErrorCode.ERR_FunctionPointerTypesInAttributeNotSupported).WithLocation(1, 1),
Copy link
Member

@jcouv jcouv Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this PR: should ERR_FunctionPointerTypesInAttributeNotSupported be marked as build-only? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private CSDiagnosticInfo? GetUnsafeDiagnosticInfo(TypeSymbol? sizeOfTypeOpt, MemorySafetyRules disallowedUnder = MemorySafetyRules.Legacy)
private CSDiagnosticInfo? GetUnsafeDiagnosticInfo(TypeSymbol? sizeOfTypeOpt, MemorySafetyRules disallowedUnder = MemorySafetyRules.Legacy, ErrorCode? customErrorCode = null)
{
Debug.Assert(sizeOfTypeOpt is null || disallowedUnder is MemorySafetyRules.Legacy);
Copy link
Member

@jcouv jcouv Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding first condition of the if below, do we have tests with updated safety rules for the scenarios where unsafe diagnostics are suppressed? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That flag is used only when binding types (BindTypeArgument and BindEventType), so there is no observable difference for the updated rules, I think.

I can add tests that hit this code path anyway, though, thanks.

{
// PROTOTYPE: What about sizeOfTypeOpt/ERR_SizeofUnsafe?
return new CSDiagnosticInfo(ErrorCode.ERR_UnsafeOperation);
return new CSDiagnosticInfo(customErrorCode ?? ErrorCode.ERR_UnsafeOperation);
Copy link
Member

@jcouv jcouv Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be checking feature availability (IDS_FeatureUnsafeEvolution) here too? #Resolved

Copy link
Member Author

@jjonescz jjonescz Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are here, the user has explicitly opted into the new unsafe rules. I thought we would check the langversion when validating the unsafe rules version (there is a PROTOTYPE comment for that validation). But I realize now we actually don't know the langversion in CSharpCompilationOptions, so it might be better to check it here after all. Thanks.


bool hasErrors = ReportUnsafeIfNotAllowed(node, diagnostics);
bool hasErrors = ReportUnsafeIfNotAllowed(node, diagnostics) ||
ReportUnsafeIfNotAllowed(node, diagnostics, disallowedUnder: MemorySafetyRules.Updated);
Copy link
Member

@jcouv jcouv Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using explicit disallowedUnder: for the first invocation. #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a PROTOTYPE comment to update all callsites, but I can update this one now since I already touched it, thanks.

Diagnostic(ErrorCode.ERR_FeatureInPreview, "stackalloc int[3]").WithArguments("updated memory safety rules").WithLocation(1, 10),
// (8,26): error CS9501: stackalloc expression without an initializer inside SkipLocalsInit may only be used in an unsafe context
// System.Span<int> a = stackalloc int[5];
Diagnostic(ErrorCode.ERR_UnsafeUninitializedStackAlloc, "stackalloc int[5]").WithLocation(8, 26),
Copy link
Member

@jcouv jcouv Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be an ERR_FeatureInPreview for stackalloc conversion in declaration of a? #Resolved

void M()
{
unsafe { System.Span<int> a = stackalloc int[5]; }
System.Span<int> b = stackalloc int[] { 1 };
Copy link
Member

@jcouv jcouv Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it still useful to keep b and d in the "UnsafeContext" test, since they are not inside an unsafe context? #Resolved

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, do we need to keep the top-level statements? (they seem redundant with previous test)

}

[Fact]
public void StackAlloc_UnsafeContext()
Copy link
Member

@jcouv jcouv Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider similar test (specifically a declaration) without SkipLocalsInit #Resolved

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done with review pass (commit 10)

@jjonescz jjonescz requested a review from jcouv November 26, 2025 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants