Browse Source

Fix assertion in ReduceNestingTransform: after copying the exitInst, it was possible that the old copy of the exitInst became unreachable.

pull/1612/head
Daniel Grunwald 6 years ago
parent
commit
6c0216bbb9
  1. 2
      ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs
  2. 12
      ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs

2
ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs

@ -354,7 +354,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -354,7 +354,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
//assert then block terminates
var trueExitInst = GetExit(ifInst.TrueInst);
var exitInst = GetExit(block);
context.Step("Negate if for desired branch "+trueExitInst, ifInst);
context.Step($"InvertIf at IL_{ifInst.StartILOffset:x4}", ifInst);
//if the then block terminates, else blocks are redundant, and should not exist
Debug.Assert(IsEmpty(ifInst.FalseInst));

12
ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs

@ -194,6 +194,18 @@ namespace ICSharpCode.Decompiler.IL @@ -194,6 +194,18 @@ namespace ICSharpCode.Decompiler.IL
// if (cond) { ...; exit; }
// ...; exit;
EnsureEndPointUnreachable(ifInst.TrueInst, exitInst);
if (ifInst.FalseInst.HasFlag(InstructionFlags.EndPointUnreachable)) {
Debug.Assert(ifInst.HasFlag(InstructionFlags.EndPointUnreachable));
Debug.Assert(ifInst.Parent == block);
int removeAfter = ifInst.ChildIndex + 1;
if (removeAfter < block.Instructions.Count) {
// Remove all instructions that ended up dead
// (this should just be exitInst itself)
Debug.Assert(block.Instructions.SecondToLastOrDefault() == ifInst);
Debug.Assert(block.Instructions.Last() == exitInst);
block.Instructions.RemoveRange(removeAfter, block.Instructions.Count - removeAfter);
}
}
ExtractElseBlock(ifInst);
ifInst = elseIfInst;
} while (ifInst != null);

Loading…
Cancel
Save