Browse Source

Merge pull request #3831 from sailro/fix-async-iterator-enumeratorcancellation

Fix #3825: reconstruct async iterators with [EnumeratorCancellation] and await in finally
fix-3860-outvar-explicit-type
Siegfried Pammer 2 days ago committed by GitHub
parent
commit
51f153d06d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 14
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncStreams.cs
  2. 11
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs

14
ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncStreams.cs

@ -71,6 +71,20 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -71,6 +71,20 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
await Task.Delay(10).ConfigureAwait(continueOnCapturedContext: false);
}
}
public static async IAsyncEnumerable<int> AwaitInFinallyWithCancellation([EnumeratorCancellation] CancellationToken cancellationToken)
{
await Task.Yield();
try
{
yield return 1;
await Task.Delay(10, cancellationToken);
}
finally
{
await Task.Yield();
}
}
}
public struct TestStruct

11
ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs

@ -911,6 +911,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -911,6 +911,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
finalStateKnown = true;
pos++;
// [optional] stfld <>u__N(ldloc this, ldnull)
// The hoisted-local cleanup may appear either before or after the combined-tokens disposal
// (the latter is present for async iterators with an [EnumeratorCancellation] token).
MatchHoistedLocalCleanup(block, ref pos);
if (pos + 2 == block.Instructions.Count && block.MatchIfAtEndOfBlock(out var condition, out var trueInst, out var falseInst))
{
if (MatchDisposeCombinedTokens(blockContainer, condition, trueInst, falseInst, blocksAnalyzed, out var setResultAndExitBlock))
@ -1088,6 +1093,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -1088,6 +1093,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
finalState = newState;
finalStateKnown = true;
}
// [optional] stfld <>u__N(ldloc this, ldnull)
// The hoisted-local cleanup may appear either before or after the combined-tokens disposal
// (the latter is present for async iterators with an [EnumeratorCancellation] token).
MatchHoistedLocalCleanup(catchBlock, ref pos);
if (pos + 2 == catchBlock.Instructions.Count && catchBlock.MatchIfAtEndOfBlock(out var condition, out var trueInst, out var falseInst))
{
if (MatchDisposeCombinedTokens(handlerContainer, condition, trueInst, falseInst, blocksAnalyzed, out var setResultAndExitBlock))

Loading…
Cancel
Save