Add SkipLocalsInitAttribute (#454)
authorAndy Gocke <angocke@microsoft.com>
Sun, 15 Dec 2019 23:13:46 +0000 (15:13 -0800)
committerJan Kotas <jkotas@microsoft.com>
Sun, 15 Dec 2019 23:13:46 +0000 (15:13 -0800)
This attribute supports a new compiler feature that allows a user to
specify that they don't want to emit the CLR `.locals init` portion of
the header in methods. This can sometimes produce a performance
improvement but, in some cases, can reveal uninitialized memory to the
application.

Fixes https://github.com/dotnet/corefx/issues/29026

src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/SkipLocalsInitAttribute.cs [new file with mode: 0644]
src/libraries/System.Runtime/ref/System.Runtime.cs
src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/AttributesTests.cs

index 98d2382..3e9aace 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeFeature.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeHelpers.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeWrappedException.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\SkipLocalsInitAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\SpecialNameAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\StateMachineAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\StringFreezingAttribute.cs" />
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/SkipLocalsInitAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/SkipLocalsInitAttribute.cs
new file mode 100644 (file)
index 0000000..fef7f11
--- /dev/null
@@ -0,0 +1,34 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Runtime.CompilerServices
+{
+    /// <summary>
+    /// Used to indicate to the compiler that the <c>.locals init</c> flag should
+    /// not be set in nested method headers when emitting to metadata.
+    /// </summary>
+    /// <remarks>
+    /// This attribute is unsafe because it may reveal uninitialized memory to
+    /// the application in certain instances (e.g., reading from uninitialized
+    /// stackalloc'd memory). If applied to a method directly, the attribute
+    /// applies to that method and all nested functions (lambdas, local
+    /// functions) below it. If applied to a type or module, it applies to all
+    /// methods nested inside. This attribute is intentionally not permitted on
+    /// assemblies. Use at the module level instead to apply to multiple type
+    /// declarations.
+    /// </remarks>
+    [AttributeUsage(AttributeTargets.Module
+        | AttributeTargets.Class
+        | AttributeTargets.Struct
+        | AttributeTargets.Constructor
+        | AttributeTargets.Method
+        | AttributeTargets.Property
+        | AttributeTargets.Event, Inherited = false)]
+    public sealed class SkipLocalsInitAttribute : Attribute
+    {
+        public SkipLocalsInitAttribute()
+        {
+        }
+    }
+}
\ No newline at end of file
index d7d8a4d..302b853 100644 (file)
@@ -6899,6 +6899,11 @@ namespace System.Runtime.CompilerServices
         public object WrappedException { get { throw null; } }
         public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
     }
+    [System.AttributeUsageAttribute(System.AttributeTargets.Module | System.AttributeTargets.Class | System.AttributeTargets.Struct | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Property | System.AttributeTargets.Event, Inherited = false)]
+    public sealed partial class SkipLocalsInitAttribute : System.Attribute
+    {
+        public SkipLocalsInitAttribute() { }
+    }
     [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Method | System.AttributeTargets.Property | System.AttributeTargets.Struct)]
     public sealed partial class SpecialNameAttribute : System.Attribute
     {
index 66ba84f..0ee7a7a 100644 (file)
@@ -9,6 +9,12 @@ namespace System.Runtime.CompilerServices.Tests
     public static class AttributesTests
     {
         [Fact]
+        public static void SkipLocalsInitAttributeTests()
+        {
+            new SkipLocalsInitAttribute();
+        }
+
+        [Fact]
         public static void AccessedThroughPropertyAttributeTests()
         {
             var attr1 = new AccessedThroughPropertyAttribute(null);