Browse Source

Fix #2964: Better error message when a method only contains a single ret instruction.

pull/2993/head
Daniel Grunwald 2 years ago
parent
commit
768cb02f0b
  1. 2
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/EmptyBodies.cs
  2. 9
      ICSharpCode.Decompiler/IL/BlockBuilder.cs
  3. 16
      ICSharpCode.Decompiler/IL/ILReader.cs

2
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/EmptyBodies.cs

@ -5,7 +5,7 @@ internal class EmptyBodies
} }
public static int RetInt() 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() public static void Nop()
{ {

9
ICSharpCode.Decompiler/IL/BlockBuilder.cs

@ -129,15 +129,6 @@ namespace ICSharpCode.Decompiler.IL
{ {
CreateContainerStructure(); CreateContainerStructure();
mainContainer.SetILRange(new Interval(0, body.GetCodeSize())); 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; currentContainer = mainContainer;
foreach (var block in basicBlocks.OrderBy(b => b.StartILOffset)) foreach (var block in basicBlocks.OrderBy(b => b.StartILOffset))

16
ICSharpCode.Decompiler/IL/ILReader.cs

@ -457,6 +457,13 @@ namespace ICSharpCode.Decompiler.IL
{ {
reader.Reset(); reader.Reset();
StoreStackForOffset(0, ImmutableStack<ILVariable>.Empty); StoreStackForOffset(0, ImmutableStack<ILVariable>.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); ILParser.SetBranchTargets(ref reader, isBranchTarget);
PrepareBranchTargetsAndStacksForExceptionHandlers(); PrepareBranchTargetsAndStacksForExceptionHandlers();
@ -1480,9 +1487,18 @@ namespace ICSharpCode.Decompiler.IL
private ILInstruction Return() private ILInstruction Return()
{ {
if (methodReturnStackType == StackType.Void) if (methodReturnStackType == StackType.Void)
{
return new IL.Leave(mainContainer); 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 else
{
return new IL.Leave(mainContainer, Pop(methodReturnStackType)); return new IL.Leave(mainContainer, Pop(methodReturnStackType));
}
} }
private ILInstruction DecodeLdstr() private ILInstruction DecodeLdstr()

Loading…
Cancel
Save