Update to latest .NET 7 Roslyn compiler (#76459)
authorJared Parsons <jaredpparsons@gmail.com>
Mon, 3 Oct 2022 20:28:32 +0000 (13:28 -0700)
committerGitHub <noreply@github.com>
Mon, 3 Oct 2022 20:28:32 +0000 (13:28 -0700)
* Patches for scoped locals

https://github.com/dotnet/roslyn/pull/64093

This change enforced that `scoped` on a local set the escape scope to
the current block where previously it was incorrectly setting to the
containing method.

* Make return and out equivalent for ref safety

https://github.com/dotnet/roslyn/pull/64318

This change allows anything returnable from a method to be assigned to
an `out` parameter. In several places had to add `scoped` to `ref` to
inform compiler they could not be captured in an `out` parameter.

* Warnings on managed pointer types

https://github.com/dotnet/roslyn/pull/64294

Compiler now issues warnings for pointer operations involving managed
types

* Update compiler version

* PR feedback

* Ref safety rules attribute

Co-authored-by: Charles Stoner <10732005+cston@users.noreply.github.com>
14 files changed:
eng/Versions.props
src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.CoreCLR.cs
src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs
src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs
src/coreclr/tools/aot/ILCompiler.Compiler.Tests/ILCompiler.Compiler.Tests.Assets/ILCompiler.Compiler.Tests.Assets.csproj
src/coreclr/tools/aot/ILCompiler.Compiler.Tests/ILCompiler.Compiler.Tests.csproj
src/libraries/System.Private.CoreLib/src/System/Number.BigInteger.cs
src/libraries/System.Private.CoreLib/src/System/Number.NumberToFloatingPointBits.cs
src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs
src/libraries/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs
src/libraries/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.cs
src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs
src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCaseEquivalences.cs

index e15a3bb..392cc63 100644 (file)
@@ -52,7 +52,7 @@
     <!--
       TODO: Remove pinned version once arcade supplies a compiler that enables the repo to compile.
     -->
-    <MicrosoftNetCompilersToolsetVersion>4.4.0-3.22452.8</MicrosoftNetCompilersToolsetVersion>
+    <MicrosoftNetCompilersToolsetVersion>4.4.0-3.22479.16</MicrosoftNetCompilersToolsetVersion>
     <StaticCsVersion>0.2.0</StaticCsVersion>
     <!-- SDK dependencies -->
     <MicrosoftDotNetApiCompatTaskVersion>8.0.100-alpha.1.22462.3</MicrosoftDotNetApiCompatTaskVersion>
index 194108b..34b53bb 100644 (file)
@@ -172,7 +172,9 @@ namespace System.Reflection.Emit
                     Span<ParameterCopyBackAction> shouldCopyBackParameters = new(ref argStorage._copyBack0, argCount);
 
                     StackAllocatedByRefs byrefStorage = default;
+#pragma warning disable CS8500
                     IntPtr* pByRefStorage = (IntPtr*)&byrefStorage;
+#pragma warning restore CS8500
 
                     CheckArguments(
                         copyOfParameters,
index c55ee60..4e1246b 100644 (file)
@@ -316,7 +316,9 @@ namespace System.Reflection
                 Span<ParameterCopyBackAction> shouldCopyBackParameters = new(ref argStorage._copyBack0, 1);
 
                 StackAllocatedByRefs byrefStorage = default;
+#pragma warning disable 8500
                 IntPtr* pByRefStorage = (IntPtr*)&byrefStorage;
+#pragma warning restore 8500
 
                 CheckArguments(
                     copyOfParameters,
index 234f8a1..4f01069 100644 (file)
@@ -235,11 +235,15 @@ namespace System.Reflection
                 StackAllocedArguments argStorage = default;
                 StackAllocatedByRefs byrefStorage = default;
 
+#pragma warning disable 8500
                 CheckArguments(ref argStorage._arg0!, (ByReference*)&byrefStorage, parameters, binderBundle);
+#pragma warning restore 8500
 
                 try
                 {
+#pragma warning disable 8500
                     ret = ref RawCalliHelper.Call(InvokeThunk, (void*)methodToCall, ref thisArg, ref ret, &byrefStorage);
+#pragma warning restore 8500
                     DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
                 }
                 catch (Exception e) when (wrapInTargetInvocationException)
@@ -268,7 +272,9 @@ namespace System.Reflection
             IntPtr* pStorage = stackalloc IntPtr[2 * argCount];
             NativeMemory.Clear(pStorage, (nuint)(2 * argCount) * (nuint)sizeof(IntPtr));
 
-            ByReference* pByRefStorage = (ByReference*)(pStorage + argCount);
+#pragma warning disable 8500
+            void* pByRefStorage = (ByReference*)(pStorage + argCount);
+#pragma warning restore 8500
 
             RuntimeImports.GCFrameRegistration regArgStorage = new(pStorage, (uint)argCount, areByRefs: false);
             RuntimeImports.GCFrameRegistration regByRefStorage = new(pByRefStorage, (uint)argCount, areByRefs: true);
@@ -326,7 +332,7 @@ namespace System.Reflection
 
         private unsafe void CheckArguments(
             ref object copyOfParameters,
-            ByReference* byrefParameters,
+            void* byrefParameters,
             object?[] parameters,
             BinderBundle binderBundle)
         {
@@ -398,8 +404,10 @@ namespace System.Reflection
 
                 Unsafe.Add(ref copyOfParameters, i) = arg!;
 
-                byrefParameters[i] = new ByReference(ref (argumentInfo.Transform & Transform.Reference) != 0 ?
+#pragma warning disable 8500, 9094
+                ((ByReference*)byrefParameters)[i] = new ByReference(ref (argumentInfo.Transform & Transform.Reference) != 0 ?
                     ref Unsafe.As<object, byte>(ref Unsafe.Add(ref copyOfParameters, i)) : ref arg.GetRawData());
+#pragma warning restore 8500, 9094
             }
         }
 
index ea167e0..605d407 100644 (file)
@@ -8,6 +8,7 @@
     <TargetFramework>netstandard2.0</TargetFramework>
     <!-- Don't add references to the netstandard platform since this is a core assembly -->
     <DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
+    <Features>noRefSafetyRulesAttribute=true</Features>
   </PropertyGroup>
 
   <ItemGroup>
index 5967b09..b09ef31 100644 (file)
@@ -14,6 +14,7 @@
     <Platforms>x86;x64</Platforms>
     <PlatformTarget>AnyCPU</PlatformTarget>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <Features>noRefSafetyRulesAttribute=true</Features>
   </PropertyGroup>
 
   <ItemGroup>    
index c19e7d0..f7e613f 100644 (file)
@@ -317,7 +317,7 @@ namespace System
             private int _length;
             private fixed uint _blocks[MaxBlockCount];
 
-            public static void Add(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result)
+            public static void Add(scoped ref BigInteger lhs, scoped ref BigInteger rhs, out BigInteger result)
             {
                 // determine which operand has the smaller length
                 ref BigInteger large = ref (lhs._length < rhs._length) ? ref rhs : ref lhs;
@@ -369,7 +369,7 @@ namespace System
                 }
             }
 
-            public static int Compare(ref BigInteger lhs, ref BigInteger rhs)
+            public static int Compare(scoped ref BigInteger lhs, scoped ref BigInteger rhs)
             {
                 Debug.Assert(unchecked((uint)(lhs._length)) <= MaxBlockCount);
                 Debug.Assert(unchecked((uint)(rhs._length)) <= MaxBlockCount);
@@ -427,7 +427,7 @@ namespace System
                 return (lastIndex * BitsPerBlock) + CountSignificantBits(value._blocks[lastIndex]);
             }
 
-            public static void DivRem(ref BigInteger lhs, ref BigInteger rhs, out BigInteger quo, out BigInteger rem)
+            public static void DivRem(scoped ref BigInteger lhs, scoped ref BigInteger rhs, out BigInteger quo, out BigInteger rem)
             {
                 // This is modified from the libraries BigIntegerCalculator.DivRem.cs implementation:
                 // https://github.com/dotnet/runtime/blob/main/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
@@ -558,6 +558,11 @@ namespace System
 
                         if (digit > 0)
                         {
+                            // rem and rhs have different lifetimes here and compiler is warning
+                            // about potential for one to copy into the other. This is a place
+                            // ref scoped parameters would alleviate.
+                            // https://github.com/dotnet/roslyn/issues/64393
+#pragma warning disable CS9080
                             // Now it's time to subtract our current quotient
                             uint carry = SubtractDivisor(ref rem, n, ref rhs, digit);
 
@@ -571,6 +576,7 @@ namespace System
 
                                 Debug.Assert(carry == 1);
                             }
+#pragma warning restore CS9080
                         }
 
                         // We have the digit!
@@ -693,7 +699,7 @@ namespace System
                 return quotient;
             }
 
-            public static void Multiply(ref BigInteger lhs, uint value, out BigInteger result)
+            public static void Multiply(scoped ref BigInteger lhs, uint value, out BigInteger result)
             {
                 if (lhs._length <= 1)
                 {
@@ -739,7 +745,7 @@ namespace System
                 }
             }
 
-            public static void Multiply(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result)
+            public static void Multiply(scoped ref BigInteger lhs, scoped ref BigInteger rhs, out BigInteger result)
             {
                 if (lhs._length <= 1)
                 {
@@ -1032,7 +1038,7 @@ namespace System
                 Multiply(ref this, value, out this);
             }
 
-            public void Multiply(ref BigInteger value)
+            public void Multiply(scoped ref BigInteger value)
             {
                 if (value._length <= 1)
                 {
@@ -1115,7 +1121,7 @@ namespace System
                 }
             }
 
-            public static void SetValue(out BigInteger result, ref BigInteger value)
+            public static void SetValue(out BigInteger result, scoped ref BigInteger value)
             {
                 int rhsLength = value._length;
                 result._length = rhsLength;
index e88014c..bec85ff 100644 (file)
@@ -794,7 +794,7 @@ namespace System
             0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648
         };
 
-        private static void AccumulateDecimalDigitsIntoBigInteger(ref NumberBuffer number, uint firstIndex, uint lastIndex, out BigInteger result)
+        private static void AccumulateDecimalDigitsIntoBigInteger(scoped ref NumberBuffer number, uint firstIndex, uint lastIndex, out BigInteger result)
         {
             BigInteger.SetZero(out result);
 
index 13ff9e3..98069a7 100644 (file)
@@ -236,6 +236,7 @@ namespace System.Reflection
                 shouldCopyBack[i] = copyBackArg;
                 copyOfParameters[i] = arg;
 
+#pragma warning disable 8500
                 if (isValueType)
                 {
 #if !MONO // Temporary until Mono is updated.
@@ -254,6 +255,7 @@ namespace System.Reflection
                     ByReference objRef = ByReference.Create(ref copyOfParameters[i]);
                     *(ByReference*)(byrefParameters + i) = objRef;
                 }
+#pragma warning restore 8500
             }
         }
 
index b1f3222..1fd9c17 100644 (file)
@@ -146,7 +146,9 @@ namespace System.Reflection
                     Span<ParameterCopyBackAction> shouldCopyBackParameters = new(ref argStorage._copyBack0, argCount);
 
                     StackAllocatedByRefs byrefStorage = default;
+#pragma warning disable 8500
                     IntPtr* pByRefStorage = (IntPtr*)&byrefStorage;
+#pragma warning restore 8500
 
                     CheckArguments(
                         copyOfParameters,
@@ -299,7 +301,9 @@ namespace System.Reflection
                     Span<ParameterCopyBackAction> shouldCopyBackParameters = new(ref argStorage._copyBack0, argCount);
 
                     StackAllocatedByRefs byrefStorage = default;
+#pragma warning disable 8500
                     IntPtr* pByRefStorage = (IntPtr*)&byrefStorage;
+#pragma warning restore 8500
 
                     CheckArguments(
                         copyOfParameters,
index 770a59d..bf534c5 100644 (file)
@@ -143,7 +143,9 @@ namespace System.Reflection
                     Span<ParameterCopyBackAction> shouldCopyBackParameters = new(ref argStorage._copyBack0, argCount);
 
                     StackAllocatedByRefs byrefStorage = default;
+#pragma warning disable 8500
                     IntPtr* pByRefStorage = (IntPtr*)&byrefStorage;
+#pragma warning restore 8500
 
                     CheckArguments(
                         copyOfParameters,
index 9e9adcd..4706b64 100644 (file)
@@ -15,7 +15,7 @@ namespace System.Text.Json
         /// Returns the span for the given reader.
         /// </summary>
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static ReadOnlySpan<byte> GetSpan(this ref Utf8JsonReader reader)
+        public static ReadOnlySpan<byte> GetSpan(this scoped ref Utf8JsonReader reader)
         {
             return reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
         }
index 65c6fd3..7cd0e3b 100644 (file)
@@ -112,12 +112,12 @@ namespace System.Text.Json
             Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length);
 
             char[]? propertyArray = null;
+            scoped Span<char> escapedPropertyName;
 
             if (firstEscapeIndexProp != -1)
             {
                 int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp);
 
-                scoped Span<char> escapedPropertyName;
                 if (length > JsonConstants.StackallocCharThreshold)
                 {
                     propertyArray = ArrayPool<char>.Shared.Rent(length);
@@ -269,12 +269,12 @@ namespace System.Text.Json
             Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length);
 
             byte[]? propertyArray = null;
+            scoped Span<byte> escapedPropertyName;
 
             if (firstEscapeIndexProp != -1)
             {
                 int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp);
 
-                scoped Span<byte> escapedPropertyName;
                 if (length > JsonConstants.StackallocByteThreshold)
                 {
                     propertyArray = ArrayPool<byte>.Shared.Rent(length);
@@ -1076,12 +1076,12 @@ namespace System.Text.Json
 
             char[]? valueArray = null;
             char[]? propertyArray = null;
+            scoped Span<char> escapedValue;
 
             if (firstEscapeIndexVal != -1)
             {
                 int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal);
 
-                scoped Span<char> escapedValue;
                 if (length > JsonConstants.StackallocCharThreshold)
                 {
                     valueArray = ArrayPool<char>.Shared.Rent(length);
@@ -1096,11 +1096,12 @@ namespace System.Text.Json
                 value = escapedValue.Slice(0, written);
             }
 
+            scoped Span<char> escapedPropertyName;
+
             if (firstEscapeIndexProp != -1)
             {
                 int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp);
 
-                scoped Span<char> escapedPropertyName;
                 if (length > JsonConstants.StackallocCharThreshold)
                 {
                     propertyArray = ArrayPool<char>.Shared.Rent(length);
@@ -1135,12 +1136,12 @@ namespace System.Text.Json
 
             byte[]? valueArray = null;
             byte[]? propertyArray = null;
+            scoped Span<byte> escapedValue;
 
             if (firstEscapeIndexVal != -1)
             {
                 int length = JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndexVal);
 
-                scoped Span<byte> escapedValue;
                 if (length > JsonConstants.StackallocByteThreshold)
                 {
                     valueArray = ArrayPool<byte>.Shared.Rent(length);
@@ -1155,11 +1156,12 @@ namespace System.Text.Json
                 utf8Value = escapedValue.Slice(0, written);
             }
 
+            scoped Span<byte> escapedPropertyName;
+
             if (firstEscapeIndexProp != -1)
             {
                 int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp);
 
-                scoped Span<byte> escapedPropertyName;
                 if (length > JsonConstants.StackallocByteThreshold)
                 {
                     propertyArray = ArrayPool<byte>.Shared.Rent(length);
@@ -1194,12 +1196,12 @@ namespace System.Text.Json
 
             byte[]? valueArray = null;
             char[]? propertyArray = null;
+            scoped Span<byte> escapedValue;
 
             if (firstEscapeIndexVal != -1)
             {
                 int length = JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndexVal);
 
-                scoped Span<byte> escapedValue;
                 if (length > JsonConstants.StackallocByteThreshold)
                 {
                     valueArray = ArrayPool<byte>.Shared.Rent(length);
@@ -1214,11 +1216,12 @@ namespace System.Text.Json
                 utf8Value = escapedValue.Slice(0, written);
             }
 
+            scoped Span<char> escapedPropertyName;
+
             if (firstEscapeIndexProp != -1)
             {
                 int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp);
 
-                scoped Span<char> escapedPropertyName;
                 if (length > JsonConstants.StackallocCharThreshold)
                 {
                     propertyArray = ArrayPool<char>.Shared.Rent(length);
@@ -1253,12 +1256,12 @@ namespace System.Text.Json
 
             char[]? valueArray = null;
             byte[]? propertyArray = null;
+            scoped Span<char> escapedValue;
 
             if (firstEscapeIndexVal != -1)
             {
                 int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal);
 
-                scoped Span<char> escapedValue;
                 if (length > JsonConstants.StackallocCharThreshold)
                 {
                     valueArray = ArrayPool<char>.Shared.Rent(length);
@@ -1273,11 +1276,12 @@ namespace System.Text.Json
                 value = escapedValue.Slice(0, written);
             }
 
+            scoped Span<byte> escapedPropertyName;
+
             if (firstEscapeIndexProp != -1)
             {
                 int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp);
 
-                scoped Span<byte> escapedPropertyName;
                 if (length > JsonConstants.StackallocByteThreshold)
                 {
                     propertyArray = ArrayPool<byte>.Shared.Rent(length);
index 7c65c63..72a6199 100644 (file)
@@ -33,7 +33,7 @@ namespace System.Text.RegularExpressions
         /// <param name="equivalences">If <paramref name="c"/> is involved in case conversion, then equivalences will contain the
         /// span of character which should be considered equal to <paramref name="c"/> in a case-insensitive comparison.</param>
         /// <returns><see langword="true"/> if <paramref name="c"/> is involved in case conversion; otherwise, <see langword="false"/></returns>
-        public static bool TryFindCaseEquivalencesForCharWithIBehavior(char c, CultureInfo culture, ref RegexCaseBehavior mappingBehavior, out ReadOnlySpan<char> equivalences)
+        public static bool TryFindCaseEquivalencesForCharWithIBehavior(char c, CultureInfo culture, scoped ref RegexCaseBehavior mappingBehavior, out ReadOnlySpan<char> equivalences)
         {
             if ((c | 0x20) == 'i' || (c | 0x01) == '\u0131')
             {