diff --git a/src/coreclr/tools/ILVerification/ILImporter.Verify.cs b/src/coreclr/tools/ILVerification/ILImporter.Verify.cs
index efa2b1018688ea..aefee9b9f9f732 100644
--- a/src/coreclr/tools/ILVerification/ILImporter.Verify.cs
+++ b/src/coreclr/tools/ILVerification/ILImporter.Verify.cs
@@ -2582,6 +2582,8 @@ void ImportLocalAlloc()
var size = Pop();
+ Check(_stackTop == 0, VerifierError.LocallocStackNotEmpty);
+
CheckIsInteger(size);
Push(StackValue.CreatePrimitive(StackValueKind.NativeInt));
diff --git a/src/coreclr/tools/ILVerification/Strings.resx b/src/coreclr/tools/ILVerification/Strings.resx
index 726cf6dd46c029..e38b197837b4a4 100644
--- a/src/coreclr/tools/ILVerification/Strings.resx
+++ b/src/coreclr/tools/ILVerification/Strings.resx
@@ -447,4 +447,7 @@
Class implements interface but not method, Class: '{0}' Interface: '{1}' Missing method: '{2}'.
+
+ Stack must be empty before localloc, except for the size item.
+
diff --git a/src/coreclr/tools/ILVerification/VerifierError.cs b/src/coreclr/tools/ILVerification/VerifierError.cs
index 4be09b1ce0213f..2d237aa9c5b083 100644
--- a/src/coreclr/tools/ILVerification/VerifierError.cs
+++ b/src/coreclr/tools/ILVerification/VerifierError.cs
@@ -190,6 +190,7 @@ public enum VerifierError
//IDS_E_GLOBAL ""
//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
}
}
diff --git a/src/tests/ilverify/ILTests/DefaultInterfaceMethod.il b/src/tests/ilverify/ILTests/DefaultInterfaceMethod.il
index a33f5cdddbe7c2..afd4f59d21e866 100644
--- a/src/tests/ilverify/ILTests/DefaultInterfaceMethod.il
+++ b/src/tests/ilverify/ILTests/DefaultInterfaceMethod.il
@@ -107,7 +107,7 @@
}
}
-.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
index 00000000000000..5789906868b1f8
--- /dev/null
+++ b/src/tests/ilverify/ILTests/LocalAllocTests.il
@@ -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
index 00000000000000..8e8765d14a524d
--- /dev/null
+++ b/src/tests/ilverify/ILTests/LocalAllocTests.ilproj
@@ -0,0 +1,3 @@
+
+
+