Unsafe evolution: handle the rest of pointer-related operations#81420
Conversation
| 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, |
There was a problem hiding this comment.
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), |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
| expectedDiagnostics = PlatformInformation.IsWindows | ||
| ? [ | ||
| // error CS8911: Using a function pointer type in this context is not supported. | ||
| Diagnostic(ErrorCode.ERR_FunctionPointerTypesInAttributeNotSupported).WithLocation(1, 1), |
There was a problem hiding this comment.
Not related to this PR: should ERR_FunctionPointerTypesInAttributeNotSupported be marked as build-only? #Closed
| 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); |
There was a problem hiding this comment.
Regarding first condition of the if below, do we have tests with updated safety rules for the scenarios where unsafe diagnostics are suppressed? #Closed
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
Should we be checking feature availability (IDS_FeatureUnsafeEvolution) here too? #Closed
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
Consider using explicit disallowedUnder: for the first invocation. #Closed
There was a problem hiding this comment.
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), |
There was a problem hiding this comment.
Should there be an ERR_FeatureInPreview for stackalloc conversion in declaration of a? #Closed
| void M() | ||
| { | ||
| unsafe { System.Span<int> a = stackalloc int[5]; } | ||
| System.Span<int> b = stackalloc int[] { 1 }; |
There was a problem hiding this comment.
Is it still useful to keep b and d in the "UnsafeContext" test, since they are not inside an unsafe context? #Closed
There was a problem hiding this comment.
Similarly, do we need to keep the top-level statements? (they seem redundant with previous test)
| } | ||
|
|
||
| [Fact] | ||
| public void StackAlloc_UnsafeContext() |
There was a problem hiding this comment.
Consider similar test (specifically a declaration) without SkipLocalsInit #Closed
jcouv
left a comment
There was a problem hiding this comment.
Done with review pass (commit 10)
|
@jcouv for another look, thanks |
Test plan: #81207
Everything under section Existing
unsaferules of the speclet should be now handled.