From 768cb02f0bf54104d8f435f8cd6736557e346886 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 1 Jun 2023 15:02:52 +0200 Subject: [PATCH] Fix #2964: Better error message when a method only contains a single ret instruction. --- .../TestCases/ILPretty/EmptyBodies.cs | 2 +- ICSharpCode.Decompiler/IL/BlockBuilder.cs | 9 --------- ICSharpCode.Decompiler/IL/ILReader.cs | 16 ++++++++++++++++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/EmptyBodies.cs b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/EmptyBodies.cs index 6945a1db1..73998e2bd 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/EmptyBodies.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/ILPretty/EmptyBodies.cs @@ -5,7 +5,7 @@ internal class EmptyBodies } public static int RetInt() { - return (int)/*Error near IL_0001: Stack underflow*/; + /*Error: Method body consists only of 'ret', but nothing is being returned. Decompiled assembly might be a reference assembly.*/; } public static void Nop() { diff --git a/ICSharpCode.Decompiler/IL/BlockBuilder.cs b/ICSharpCode.Decompiler/IL/BlockBuilder.cs index be06a5034..c21881673 100644 --- a/ICSharpCode.Decompiler/IL/BlockBuilder.cs +++ b/ICSharpCode.Decompiler/IL/BlockBuilder.cs @@ -129,15 +129,6 @@ namespace ICSharpCode.Decompiler.IL { CreateContainerStructure(); mainContainer.SetILRange(new Interval(0, body.GetCodeSize())); - if (!basicBlocks.Any()) - { - mainContainer.Blocks.Add(new Block { - Instructions = { - new InvalidBranch("Empty body found. Decompiled assembly might be a reference assembly.") - } - }); - return; - } currentContainer = mainContainer; foreach (var block in basicBlocks.OrderBy(b => b.StartILOffset)) diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index 8b1072967..901076a22 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -457,6 +457,13 @@ namespace ICSharpCode.Decompiler.IL { reader.Reset(); StoreStackForOffset(0, ImmutableStack.Empty); + if (reader.Length == 0) + { + blocksByOffset[0].Block.Instructions.Add( + new InvalidBranch("Empty body found. Decompiled assembly might be a reference assembly.") + ); + return; + } ILParser.SetBranchTargets(ref reader, isBranchTarget); PrepareBranchTargetsAndStacksForExceptionHandlers(); @@ -1480,9 +1487,18 @@ namespace ICSharpCode.Decompiler.IL private ILInstruction Return() { if (methodReturnStackType == StackType.Void) + { return new IL.Leave(mainContainer); + } + else if (currentInstructionStart == 0) + { + Debug.Assert(expressionStack.Count == 0 && currentStack.IsEmpty); + return new InvalidBranch("Method body consists only of 'ret', but nothing is being returned. Decompiled assembly might be a reference assembly."); + } else + { return new IL.Leave(mainContainer, Pop(methodReturnStackType)); + } } private ILInstruction DecodeLdstr()