From 4f4ca482be9c448768a8ce9c737d91ec7ec8a137 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sun, 21 Jun 2020 19:31:40 +0200 Subject: [PATCH] Fix #1950: Fix crash when finallyMethod cannot be found. This seems to be possible due to a C# compiler bug. --- .../IL/ControlFlow/YieldReturnDecompiler.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs b/ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs index d028db7fc..268891509 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs @@ -1002,9 +1002,10 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow void CreateTryBlock(Block block, int state) { var finallyMethod = FindFinallyMethod(state); - Debug.Assert(finallyMethod != null); - // remove the method so that it doesn't cause ambiguity when processing nested try-finally blocks - finallyMethodToStateRange.Remove(finallyMethod); + if (finallyMethod != null) { + // remove the method so that it doesn't cause ambiguity when processing nested try-finally blocks + finallyMethodToStateRange.Remove(finallyMethod); + } var tryBlock = new Block(); tryBlock.AddILRange(block); @@ -1015,7 +1016,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow stateToContainer.Add(state, tryBlockContainer); ILInstruction finallyBlock; - if (decompiledFinallyMethods.TryGetValue(finallyMethod, out var decompiledMethod)) { + if (finallyMethod == null) { + finallyBlock = new InvalidBranch($"Could not find finallyMethod for state={state}.\n" + + $"Possibly this method is affected by a C# compiler bug that causes the finally body\n" + + $"not to run in case of an exception or early 'break;' out of a loop consuming this iterable."); + } else if (decompiledFinallyMethods.TryGetValue(finallyMethod, out var decompiledMethod)) { finallyBlock = decompiledMethod.function.Body; var vars = decompiledMethod.function.Variables.ToArray(); decompiledMethod.function.Variables.Clear();