You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The compiler should report an error about references to out-of-scope stack memory generated by [UnscopedRef], defensively copied struct and pattern matching
#75484
Open
TessenR opened this issue
Oct 11, 2024
· 1 comment
· May be fixed by #75511
Microsoft Visual Studio Professional 2022
Version 17.12.0 Preview 2.1
VisualStudio.17.Preview/17.12.0-pre.2.1+35323.107
Microsoft .NET Framework
Version 4.8.09037
Steps to Reproduce:
Compile and run the following code:
using System;using System.Runtime.CompilerServices;using System.Diagnostics.CodeAnalysis;using System.Runtime.InteropServices;namespace Net7Test;internalclassProgram{privatestaticreadonlyVec4ReadOnlyVec=new Vec4(1,2,3,4);staticvoidMain(string[]args){
Console.WriteLine(RuntimeInformation.FrameworkDescription);// This refers to stack memory that has already been left out.ref Vec4 foo=ref Foo().x;foo=new Vec4(0,0,0,0);
Console.WriteLine(foo.X);
MakeStackDirty();
Console.WriteLine(foo.X);
Console.WriteLine(foo);}[MethodImpl(MethodImplOptions.NoInlining)]privatestatic Wrapper Foo(){// Defensive copy occurs and it is placed in stack memory implicitly.// The method returns a reference to the copy, which happens invalid memory access.if(ReadOnlyVec is var (x, _))returnx;thrownull!;}[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]privatestaticvoidMakeStackDirty(){Span<byte>mem=stackallocbyte[1028];
mem.Clear();}}publicstructVec4{publicfloatX,Y,Z,W;publicVec4(floatx,floaty,floatz,floatw)=>(X, Y, Z, W)=(x, y, z, w);[UnscopedRef]publicref Vec4 Self =>refthis;[UnscopedRef]publicvoidDeconstruct(outWrapperx,outVec4y){x=new Wrapper(refthis);y=Self;}publicoverridestringToString()=>$"<{X}, {Y}, {Z}, {W}>";}publicrefstructWrapper{publicref Vec4 x;publicWrapper(refVec4X){x=ref X;}[UnscopedRef]publicref Vec4 Self =>ref x;publicoverridestringToString()=> x.ToString();}
Diagnostic Id:
CS8352: Cannot use variable in this context because it may expose referenced variables outside of their declaration scope
Expected Behavior:
There should be an error for return x; in Foo as it returns a ref struct wrapping a reference to stack memory that's going to be left out.
Version Used:
Steps to Reproduce:
Compile and run the following code:
Diagnostic Id:
CS8352: Cannot use variable in this context because it may expose referenced variables outside of their declaration scope
Expected Behavior:
There should be an error for
return x;
inFoo
as it returns a ref struct wrapping a reference to stack memory that's going to be left out.Actual Behavior:
The code compiles and prints
Notes:
This is a variation of #64776 using pattern matching which Roslyn fails to verify
If you replace
with an explicit call to
Deconstruct
Roslyn will correctly report an error:The text was updated successfully, but these errors were encountered: