Browse Source

Fix #3323: Simplify cleanup in AwaitInFinallyTransform, ensuring that we do not miss any containers.

null-coalescing-assignment
Daniel Grunwald 4 months ago
parent
commit
02d9dc3e85
  1. 4
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  2. 19
      ICSharpCode.Decompiler/IL/ControlFlow/AwaitInFinallyTransform.cs

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

@ -162,8 +162,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (!isVisualBasicStateMachine) if (!isVisualBasicStateMachine)
{ {
context.StepStartGroup("AwaitInCatchTransform");
AwaitInCatchTransform.Run(function, context); AwaitInCatchTransform.Run(function, context);
context.StepEndGroup();
context.StepStartGroup("AwaitInFinallyTransform");
AwaitInFinallyTransform.Run(function, context); AwaitInFinallyTransform.Run(function, context);
context.StepEndGroup();
} }
awaitDebugInfos.SortBy(row => row.YieldOffset); awaitDebugInfos.SortBy(row => row.YieldOffset);

19
ICSharpCode.Decompiler/IL/ControlFlow/AwaitInFinallyTransform.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
{ {
if (!context.Settings.AwaitInCatchFinally) if (!context.Settings.AwaitInCatchFinally)
return; return;
HashSet<BlockContainer> changedContainers = new HashSet<BlockContainer>(); bool needsUnreachableCodeCleanup = false;
// analyze all try-catch statements in the function // analyze all try-catch statements in the function
foreach (var tryCatch in function.Descendants.OfType<TryCatch>().ToArray()) foreach (var tryCatch in function.Descendants.OfType<TryCatch>().ToArray())
@ -130,7 +130,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
context.StepStartGroup("Inline finally block with await", tryCatch.Handlers[0]); context.StepStartGroup("Inline finally block with await", tryCatch.Handlers[0]);
var cfg = new ControlFlowGraph(container, context.CancellationToken); var cfg = new ControlFlowGraph(container, context.CancellationToken);
changedContainers.Add(container); needsUnreachableCodeCleanup = true;
var finallyContainer = new BlockContainer().WithILRange(catchBlockContainer); var finallyContainer = new BlockContainer().WithILRange(catchBlockContainer);
tryCatch.ReplaceWith(new TryFinally(tryCatch.TryBlock, finallyContainer).WithILRange(tryCatch.TryBlock)); tryCatch.ReplaceWith(new TryFinally(tryCatch.TryBlock, finallyContainer).WithILRange(tryCatch.TryBlock));
@ -182,11 +182,16 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
context.Step("Clean up", function); context.Step("Clean up", function);
// clean up all modified containers if (needsUnreachableCodeCleanup)
foreach (var container in changedContainers) {
container.SortBlocks(deleteUnreachableBlocks: true); // Cleaning up only the modified containers is insufficient, deleting blocks in
// any container can also cause other blocks in parent containers to become unreachable.
((BlockContainer)function.Body).SortBlocks(deleteUnreachableBlocks: true); // So we just clean up everything.
foreach (var container in function.Body.Descendants.OfType<BlockContainer>())
{
container.SortBlocks(deleteUnreachableBlocks: true);
}
}
void MoveDominatedBlocksToContainer(Block newEntryPoint, Block endBlock, ControlFlowGraph graph, void MoveDominatedBlocksToContainer(Block newEntryPoint, Block endBlock, ControlFlowGraph graph,
BlockContainer targetContainer) BlockContainer targetContainer)

Loading…
Cancel
Save