cecilifier
cecilifier copied to clipboard
Failure to consume returned value from method calls generates invalid code
StatementExpressions containing non-void method invocations generates code missing a Pop instruction.
For example, running the generated assembly from the cecilified code for the following snippet
M("X");
void M(string s) => s.ToUpper();
results in runtime exception:
Unhandled exception. System.InvalidProgramException: Common Language Runtime detected an invalid program.
at Program.<<Main>$>g__M|0_0(String s)
at Program.<Main>$(String[] args)
running ilverify with the following command:
ilverify output.dll -r "/usr/lib/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.5/ref/net9.0/*.dll"
results:
[IL]: Error [ReturnVoid]: [/tmp/Foo/output.dll : Program::<<Main>$>g__M|0_0(string)][offset 0x00000006][found ref 'string'] Stack must be empty on return from a void function.
1 Error(s) Verifying /tmp/Foo/output.dll
indicating that a value from the stack was not consumed as expected.
Looking into the IL for function M() it become evident that it is missing a Pop instruction:
.method assembly hidebysig static
void '<<Main>$>g__M|0_0' (
string s
) cil managed
{
// Method begins at RVA 0x2070
// Header size: 12
// Code size: 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: callvirt instance string [System.Runtime]System.String::ToUpper()
// MISSING POP
IL_0006: ret
}