diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 581380e6d..b9320c5b4 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -271,6 +271,7 @@ + diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs index 268b9a429..d93a5b58a 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs @@ -176,10 +176,19 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow if (DetectExitPoints.CompatibleExitInstruction(trueExitInst, falseExitInst)) { // if (...) { ...; goto exitPoint; } goto nextBlock; nextBlock: ...; goto exitPoint; // -> if (...) { ... } else { ... } goto exitPoint; - context.Step("Inline block as else-branch", ifInst); - targetBlock.Instructions.RemoveAt(targetBlock.Instructions.Count - 1); - targetBlock.Remove(); - ifInst.FalseInst = targetBlock; + + // the else block is not empty or nop-only: + if (!targetBlock.IsNopBlock(ignoreExitPoint: falseExitInst)) { + context.Step("Inline block as else-branch", ifInst); + targetBlock.Instructions.RemoveAt(targetBlock.Instructions.Count - 1); + targetBlock.Remove(); + ifInst.FalseInst = targetBlock; + } else { + // the else block is empty or nop-only and can be safely removed: + context.Step("Remove empty else-branch", ifInst); + targetBlock.Instructions.RemoveAt(targetBlock.Instructions.Count - 1); + targetBlock.Remove(); + } exitInst = block.Instructions[block.Instructions.Count - 1] = falseExitInst; Block trueBlock = ifInst.TrueInst as Block; if (trueBlock != null) { diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs b/ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs new file mode 100644 index 000000000..c363dd1de --- /dev/null +++ b/ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs @@ -0,0 +1,20 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; + +namespace ICSharpCode.Decompiler.IL +{ + public static class ILInstructionExtensions + { + /// + /// Determines whether a block only consists of nop instructions or is empty. + /// + public static bool IsNopBlock(this Block block, ILInstruction ignoreExitPoint = null) + { + if (block == null) + throw new ArgumentNullException(nameof(block)); + return block.Children.Count(i => !(i is Nop) && i != ignoreExitPoint) == 0; + } + } +}