cecilifier icon indicating copy to clipboard operation
cecilifier copied to clipboard

Failure to consume returned value from method calls generates invalid code

Open adrianoc opened this issue 9 months ago • 0 comments

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
}

adrianoc avatar May 17 '25 20:05 adrianoc