diff --git a/ICSharpCode.Decompiler/ILAst/GotoRemoval.cs b/ICSharpCode.Decompiler/ILAst/GotoRemoval.cs index 302bdeb32..15e9984aa 100644 --- a/ICSharpCode.Decompiler/ILAst/GotoRemoval.cs +++ b/ICSharpCode.Decompiler/ILAst/GotoRemoval.cs @@ -64,7 +64,7 @@ namespace ICSharpCode.Decompiler.ILAst int count = ilCase.Body.Count; if (count >= 2) { - if (!ilCase.Body[count - 2].CanFallthough() && + if (!ilCase.Body[count - 2].CanFallThough() && ilCase.Body[count - 1].Match(ILCode.LoopOrSwitchBreak)) { ilCase.Body.RemoveAt(count - 1); } diff --git a/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs b/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs index 6e77e3a9c..6aa3f352c 100644 --- a/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs +++ b/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs @@ -350,17 +350,22 @@ namespace ICSharpCode.Decompiler.ILAst // Inline return statement ILNode target; List retArgs; - if (nextSibling.TryGetValue(targetLabel, out target) && - target.Match(ILCode.Ret, out retArgs)) - { - ILVariable locVar; - object constValue; - if (retArgs.Count == 0) { + if (nextSibling.TryGetValue(targetLabel, out target)) { + if (target.Match(ILCode.Ret, out retArgs)) { + ILVariable locVar; + object constValue; + if (retArgs.Count == 0) { + block.Body[i] = new ILExpression(ILCode.Ret, null); + } else if (retArgs.Single().Match(ILCode.Ldloc, out locVar)) { + block.Body[i] = new ILExpression(ILCode.Ret, null, new ILExpression(ILCode.Ldloc, locVar)); + } else if (retArgs.Single().Match(ILCode.Ldc_I4, out constValue)) { + block.Body[i] = new ILExpression(ILCode.Ret, null, new ILExpression(ILCode.Ldc_I4, constValue)); + } + } + } else { + if (method.Body.Count > 0 && method.Body.Last() == targetLabel) { + // It exits the main method - so it is same as return; block.Body[i] = new ILExpression(ILCode.Ret, null); - } else if (retArgs.Single().Match(ILCode.Ldloc, out locVar)) { - block.Body[i] = new ILExpression(ILCode.Ret, null, new ILExpression(ILCode.Ldloc, locVar)); - } else if (retArgs.Single().Match(ILCode.Ldc_I4, out constValue)) { - block.Body[i] = new ILExpression(ILCode.Ret, null, new ILExpression(ILCode.Ldc_I4, constValue)); } } } @@ -796,8 +801,8 @@ namespace ICSharpCode.Decompiler.ILAst for (int i = 0; i < block.Body.Count; i++) { ILCondition cond = block.Body[i] as ILCondition; if (cond != null) { - bool trueExits = cond.TrueBlock.Body.Count > 0 && !cond.TrueBlock.Body.Last().CanFallthough(); - bool falseExits = cond.FalseBlock.Body.Count > 0 && !cond.FalseBlock.Body.Last().CanFallthough(); + bool trueExits = cond.TrueBlock.Body.Count > 0 && !cond.TrueBlock.Body.Last().CanFallThough(); + bool falseExits = cond.FalseBlock.Body.Count > 0 && !cond.FalseBlock.Body.Last().CanFallThough(); if (trueExits) { // Move the false block after the condition @@ -899,19 +904,11 @@ namespace ICSharpCode.Decompiler.ILAst return false; } - public static bool CanFallthough(this ILNode node) + public static bool CanFallThough(this ILNode node) { ILExpression expr = node as ILExpression; if (expr != null) { - switch(expr.Code) { - case ILCode.Br: - case ILCode.Ret: - case ILCode.Throw: - case ILCode.Rethrow: - case ILCode.LoopContinue: - case ILCode.LoopOrSwitchBreak: - return false; - } + return expr.Code.CanFallThough(); } return true; } diff --git a/ICSharpCode.Decompiler/ILAst/ILCodes.cs b/ICSharpCode.Decompiler/ILAst/ILCodes.cs index 43acc361e..afb79315c 100644 --- a/ICSharpCode.Decompiler/ILAst/ILCodes.cs +++ b/ICSharpCode.Decompiler/ILAst/ILCodes.cs @@ -286,6 +286,8 @@ namespace ICSharpCode.Decompiler.ILAst case ILCode.Endfinally: case ILCode.Throw: case ILCode.Rethrow: + case ILCode.LoopContinue: + case ILCode.LoopOrSwitchBreak: return false; default: return true;