This repository was archived by the owner on Jul 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 153
This repository was archived by the owner on Jul 15, 2023. It is now read-only.
CCRewriter produces invalid IL on async method or iterator blocks #38
Copy link
Copy link
Closed
Milestone
Description
Code Contracts version: 1.7.11202.10 (reproduces on earlier versions as well).
Perform Runtime Contract Checking != Full
Debug/Release: both
Using CCRewrite with Perform Runtime Contract Checking not equals to Full with async method (or methods with iterator blocks) with complex Contract.Requires (that has II or && in it) provides invalid assembly. Using such an assembly leads to System.InvalidProgramExecution exception and peverify shows following error:
[IL]: Error: [PATHToExecutable\CcRewriterBug\bin\Release\CCRewriterBug.exe:
CcRewriterBug.Program+<FooEnumerable>d__3::MoveNext][offset 0x00000021] Stack underflow
Steps to reproduce:
static async Task FooAsync(string str)
{
// Works fine with Contract.Requires(str != null);
Contract.Requires(str != null && str.Length > 1);
await Task.Delay(42);
}or
static IEnumerable<string> FooEnumerable(string str)
{
Contract.Requires(str != null && str.Length > 1);
yield return str;
}In latter case if Perform Runtime Contract Checking is not Full CCRewrite produces following IL in MoveMethod:
.method private final hidebysig newslot virtual
instance bool MoveNext () cil managed
{
.override method instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
// Method begins at RVA 0x21ac
// Code size 64 (0x40)
.maxstack 2
.locals init (
[0] int32 CS$0$0000
)
IL_0000: ldarg.0
IL_0001: ldfld int32 CcRewriterBug.Program/'<FooEnumerable>d__0'::'<>1__state'
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: switch (IL_001a, IL_0037)
IL_0015: br IL_003e
IL_001a: ldarg.0
IL_001b: ldc.i4.m1
IL_001c: stfld int32 CcRewriterBug.Program/'<FooEnumerable>d__0'::'<>1__state'
IL_0021: pop // this instruction is invalid!
IL_0022: ldarg.0
IL_0023: ldarg.0
IL_0024: ldfld string CcRewriterBug.Program/'<FooEnumerable>d__0'::str
IL_0029: stfld string CcRewriterBug.Program/'<FooEnumerable>d__0'::'<>2__current'
IL_002e: ldarg.0
IL_002f: ldc.i4.1
IL_0030: stfld int32 CcRewriterBug.Program/'<FooEnumerable>d__0'::'<>1__state'
IL_0035: ldc.i4.1
IL_0036: ret
IL_0037: ldarg.0
IL_0038: ldc.i4.m1
IL_0039: stfld int32 CcRewriterBug.Program/'<FooEnumerable>d__0'::'<>1__state'
IL_003e: ldc.i4.0
IL_003f: ret
} // end of method '<FooEnumerable>d__0'::MoveNext```
Reactions are currently unavailable