From 6c0216bbb9042c55ebee854d32d54afd25090747 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 26 Jul 2019 17:13:47 +0200 Subject: [PATCH] Fix assertion in ReduceNestingTransform: after copying the exitInst, it was possible that the old copy of the exitInst became unreachable. --- .../IL/ControlFlow/ConditionDetection.cs | 2 +- .../IL/Transforms/ReduceNestingTransform.cs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs index 7025208f1..bb7a120b1 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs @@ -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)); diff --git a/ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs index cdd1822a0..e73fab690 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs @@ -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);