From e2b10adc72260538ed52badc4233d95197cae1e7 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 15 Feb 2020 10:24:51 +0100 Subject: [PATCH] Fix #1927: NRE in ExpressionBuilder when trying to decompile catch-when blocks consisting of multiple statements. --- ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 1a5a0b2daf..3e045f087c 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1970,11 +1970,21 @@ protected internal override TranslatedExpression VisitBlockContainer(BlockContai var body = statementBuilder.ConvertAsBlock(container); body.InsertChildAfter(null, new Comment(" Could not convert BlockContainer to single expression"), Roles.Comment); var ame = new AnonymousMethodExpression { Body = body }; - var delegateType = new ParameterizedType(compilation.FindType(typeof(Func<>)), InferReturnType(body)); + var systemFuncType = compilation.FindType(typeof(Func<>)); + var blockReturnType = InferReturnType(body); + var delegateType = new ParameterizedType(systemFuncType, blockReturnType); var invocationTarget = new CastExpression(ConvertType(delegateType), ame); + ResolveResult rr; + // This might happen when trying to decompile an assembly built for a target framework where System.Func does not exist yet. + if (systemFuncType.Kind == TypeKind.Unknown) { + rr = new ResolveResult(blockReturnType); + } else { + var invokeMethod = delegateType.GetDelegateInvokeMethod(); + rr = new CSharpInvocationResolveResult(new ResolveResult(delegateType), invokeMethod, EmptyList.Instance); + } return new InvocationExpression(new MemberReferenceExpression(invocationTarget, "Invoke")) .WithILInstruction(container) - .WithRR(new CSharpInvocationResolveResult(new ResolveResult(delegateType), delegateType.GetDelegateInvokeMethod(), EmptyList.Instance)); + .WithRR(rr); } finally { statementBuilder.currentReturnContainer = oldReturnContainer; statementBuilder.currentResultType = oldResultType;