Skip to content

Commit

Permalink
Fix #3071 BlockBuilder assertion for unreachable try-block
Browse files Browse the repository at this point in the history
  • Loading branch information
dgrunwald committed Sep 29, 2023
1 parent 1327a0d commit 5206aef
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions ICSharpCode.Decompiler/IL/ILReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ void ReadInstructions(CancellationToken cancellationToken)
ImportedBlock block = importQueue.Dequeue();
ReadBlock(block, cancellationToken);
}
EnsureExceptionHandlersHaveBlocks();

// Merge different variables for same stack slot:
var unionFind = CheckOutgoingEdges();
Expand Down Expand Up @@ -616,6 +617,26 @@ private void PrepareBranchTargetsAndStacksForExceptionHandlers()
}
}

private void EnsureExceptionHandlersHaveBlocks()
{
// PrepareBranchTargetsAndStacksForExceptionHandlers enqueued filter/handler offsets
// so we have blocks for those; but it's possible that the TryOffset was never enqueued
// because it is unreachable.
// We need to ensure that we have blocks for all exception handler offsets,
// as otherwise the BlockBuilder will fail.
foreach (var eh in body.ExceptionRegions)
{
if (blocksByOffset.ContainsKey(eh.TryOffset))
continue;
// Create a dummy block for the try offset
var block = new ImportedBlock(eh.TryOffset, ImmutableStack<ILVariable>.Empty);
block.Block.Instructions.Add(new InvalidBranch("Unreachable try block"));
blocksByOffset.Add(eh.TryOffset, block);
}
// Note that after the BlockBuilder is done, it may delete the whole block containing
// the unreachable try-except construct, if it is completely unreachable.
}

private static bool IsSequencePointInstruction(ILInstruction instruction)
{
if (instruction.OpCode is OpCode.Nop
Expand Down

0 comments on commit 5206aef

Please sign in to comment.