diff --git a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs index e1e52288b..510ee1067 100644 --- a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs @@ -198,8 +198,8 @@ namespace ICSharpCode.Decompiler.Tests RunCS(options: options); } - [Test, Ignore("Run() method cannot be fully decompiled.")] - public void Async([ValueSource("defaultOptions")] CompilerOptions options) + [Test] + public void Async([Values(CompilerOptions.None, CompilerOptions.Optimize)] CompilerOptions options) { RunCS(options: options); } diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs index 44cd59c8e..bf83b4334 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs @@ -774,17 +774,26 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow return false; if (!target.MatchLdThis()) return false; - if (field.MemberDefinition != awaiterField) + if (!field.Equals(awaiterField)) return false; pos++; // stfld awaiterField(ldloc this, default.value) if (block.Instructions[pos].MatchStFld(out target, out field, out value) && target.MatchLdThis() - && field.MemberDefinition == awaiterField + && field.Equals(awaiterField) && value.OpCode == OpCode.DefaultValue) { pos++; + } else { + // {stloc V_6(default.value System.Runtime.CompilerServices.TaskAwaiter)} + // {stobj System.Runtime.CompilerServices.TaskAwaiter`1[[System.Int32]](ldflda <>u__$awaiter4(ldloc this), ldloc V_6) at IL_0163} + if (block.Instructions[pos].MatchStLoc(out var variable, out value) && value.OpCode == OpCode.DefaultValue + && block.Instructions[pos + 1].MatchStFld(out target, out field, out value) + && field.Equals(awaiterField) + && value.MatchLdLoc(variable)) { + pos += 2; + } } // stloc S_28(ldc.i4 -1) @@ -804,7 +813,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow if (block.Instructions[pos].MatchStFld(out target, out field, out value)) { if (!target.MatchLdThis()) return false; - if (field.MemberDefinition != stateField) + if (!field.MemberDefinition.Equals(stateField.MemberDefinition)) return false; if (!(value.MatchLdcI4(initialState) || value.MatchLdLoc(m1Var))) return false;