roslyn: Compiler emits incorrect sequence point in Release builds
Version Used:
Version 17.8.0 Preview 1.0 [33919.582.main]
Steps to Reproduce:
Test:
[Fact]
public void Release()
{
var source = @"
class C
{
public void F()
{
object c1 = new object();
object c2 = new object();
G(c1, c2);
}
public static int G(object o1, object o2) => 1;
}
";
var v = CompileAndVerify(source, options: TestOptions.ReleaseDll);
v.VerifyMethodBody("C.F", @"
{
// Code size 19 (0x13)
.maxstack 2
.locals init (object V_0) //c2
// sequence point: object c1 = new object();
IL_0000: newobj ""object..ctor()""
// sequence point: object c2 = new object();
IL_0005: newobj ""object..ctor()""
IL_000a: stloc.0
// sequence point: G(c1, c2);
IL_000b: ldloc.0
IL_000c: call ""int C.G(object, object)""
IL_0011: pop
// sequence point: }
IL_0012: ret
}
");
}
The evaluation stack is not empty at IL offsets 0c5 and 0xb, where sequences points object c2 = new object();
and G(c1, c2);
are placed.
Seems like c1
is optimized to eval stack, which causes subsequent sequence points to be placed on non-empty eval stack.
It’s not clear to me why c1
is optimized but c2
isn’t. If the optimization is desirable, then we should skip the subsequent sequence points that don’t have empty eval stack.
About this issue
- Original URL
- State: open
- Created a year ago
- Comments: 17 (10 by maintainers)
Yes, we do honor it in debug builds. The only problem is some optimizations in release builds.
IIRC, switch expressions use stack spilling in order to allow sequence points to be placed.