Add localloc empty stack verification (#73109)
authorDenis Proshutinskii <36221916+jl0pd@users.noreply.github.com>
Mon, 1 Aug 2022 08:12:24 +0000 (15:12 +0700)
committerGitHub <noreply@github.com>
Mon, 1 Aug 2022 08:12:24 +0000 (01:12 -0700)
* Add localloc empty stack verification
* Update error message
* Add more tests
* Fix tests

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Dan Moseley <danmose@microsoft.com>
src/coreclr/tools/ILVerification/ILImporter.Verify.cs
src/coreclr/tools/ILVerification/Strings.resx
src/coreclr/tools/ILVerification/VerifierError.cs
src/tests/ilverify/ILTests/DefaultInterfaceMethod.il
src/tests/ilverify/ILTests/LocalAllocTests.il [new file with mode: 0644]
src/tests/ilverify/ILTests/LocalAllocTests.ilproj [new file with mode: 0644]

index efa2b10..aefee9b 100644 (file)
@@ -2582,6 +2582,8 @@ namespace Internal.IL
 
             var size = Pop();
 
+            Check(_stackTop == 0, VerifierError.LocallocStackNotEmpty);
+
             CheckIsInteger(size);
 
             Push(StackValue.CreatePrimitive(StackValueKind.NativeInt));
index 726cf6d..e38b197 100644 (file)
   <data name="InterfaceMethodNotImplemented" xml:space="preserve">
     <value>Class implements interface but not method, Class: '{0}' Interface: '{1}' Missing method: '{2}'.</value>
   </data>
+  <data name="LocallocStackNotEmpty" xml:space="preserve">
+    <value>Stack must be empty before localloc, except for the size item.</value>
+  </data>
 </root>
index 4be09b1..2d237aa 100644 (file)
@@ -190,6 +190,7 @@ namespace ILVerify
         //IDS_E_GLOBAL         "<GlobalFunction>"
         //IDS_E_MDTOKEN        "[mdToken=0x%x]"
         InterfaceImplHasDuplicate,            // InterfaceImpl has a duplicate
-        InterfaceMethodNotImplemented         // Class implements interface but not method
+        InterfaceMethodNotImplemented,         // Class implements interface but not method
+        LocallocStackNotEmpty, // localloc requires that stack must be empty, except for 'size' argument
     }
 }
index a33f5cd..afd4f59 100644 (file)
        }
 }
 
-.class public auto ansi beforefieldinit ChildClassInheritsFromInterfaceWithDefaultImplementationWhereChildInterfaceReabstractsInterfaceMethod_InvalidType_InterfaceMethodNotImplemented
+.class public auto ansi beforefieldinit ChildClassInheritsFromInterfaceWithDefaultImplementationWhereChildInterfaceReabstractsInterfaceMethod_InvalidType_InterfaceMethodNotImplemented@InterfaceMethodNotImplemented
        extends [System.Runtime]System.Object
        implements IReabstractDefaultImplementation, IInheritedDefaultImplInterface, IInterface
 {
diff --git a/src/tests/ilverify/ILTests/LocalAllocTests.il b/src/tests/ilverify/ILTests/LocalAllocTests.il
new file mode 100644 (file)
index 0000000..5789906
--- /dev/null
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+.assembly extern System.Runtime
+{
+}
+
+.assembly extern LocalAllocTestsFriend
+{
+}
+
+.assembly LocalAllocTests
+{
+}
+
+.class public auto ansi beforefieldinit LocAllocTests
+        extends [System.Runtime]System.Object
+{
+    .method private hidebysig instance void Load.LocAllocShouldFailWhenStackNotEmpty_Invalid_Unverifiable.LocallocStackNotEmpty() cil managed
+    {
+        ldnull // pretend there's meaningfull value on stack
+        ldc.i4.2 // size parameter for localloc
+        localloc
+        pop // pop localloc pointer
+        pop // pop ldnull
+        ret
+    }
+
+    .method private hidebysig instance void Load.LocAllocShouldFailWhenSizeIsAbsent_Invalid_Unverifiable.StackUnderflow() cil managed
+    {
+        localloc
+        pop // pop localloc pointer
+        ret
+    }
+
+    .method private hidebysig instance void Load.LocAllocShouldSuccesWhenSizeIsPresent_Invalid_Unverifiable() cil managed
+    {
+        ldc.i4.2 // size parameter for localloc
+        localloc
+        pop // pop localloc pointer
+        ret
+    }
+}
diff --git a/src/tests/ilverify/ILTests/LocalAllocTests.ilproj b/src/tests/ilverify/ILTests/LocalAllocTests.ilproj
new file mode 100644 (file)
index 0000000..8e8765d
--- /dev/null
@@ -0,0 +1,3 @@
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="ILTests.targets" />
+</Project>