Browse Source

Fix #2039: "Could not convert BlockContainer to single expression" workaround produces uncompilable code - potentially unassigned variables.

pull/2145/head
Siegfried Pammer 5 years ago
parent
commit
d8b1f1f8d2
  1. 14
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

14
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -2328,14 +2328,19 @@ namespace ICSharpCode.Decompiler.CSharp
try try
{ {
var body = statementBuilder.ConvertAsBlock(container); var body = statementBuilder.ConvertAsBlock(container);
body.InsertChildAfter(null, new Comment(" Could not convert BlockContainer to single expression"), Roles.Comment); var comment = new Comment(" Could not convert BlockContainer to single expression");
body.InsertChildAfter(null, comment, Roles.Comment);
// set ILVariable.HasInitialValue for any variables being used inside the container
foreach (var stloc in container.Descendants.OfType<StLoc>())
stloc.Variable.HasInitialValue = true;
var ame = new AnonymousMethodExpression { Body = body }; var ame = new AnonymousMethodExpression { Body = body };
var systemFuncType = compilation.FindType(typeof(Func<>)); var systemFuncType = compilation.FindType(typeof(Func<>));
var blockReturnType = InferReturnType(body); var blockReturnType = InferReturnType(body);
var delegateType = new ParameterizedType(systemFuncType, blockReturnType); var delegateType = new ParameterizedType(systemFuncType, blockReturnType);
var invocationTarget = new CastExpression(ConvertType(delegateType), ame); var invocationTarget = new CastExpression(ConvertType(delegateType), ame);
ResolveResult rr; ResolveResult rr;
// This might happen when trying to decompile an assembly built for a target framework where System.Func<T> does not exist yet. // This might happen when trying to decompile an assembly built for a target framework
// where System.Func<T> does not exist yet.
if (systemFuncType.Kind == TypeKind.Unknown) if (systemFuncType.Kind == TypeKind.Unknown)
{ {
rr = new ResolveResult(blockReturnType); rr = new ResolveResult(blockReturnType);
@ -2343,7 +2348,10 @@ namespace ICSharpCode.Decompiler.CSharp
else else
{ {
var invokeMethod = delegateType.GetDelegateInvokeMethod(); var invokeMethod = delegateType.GetDelegateInvokeMethod();
rr = new CSharpInvocationResolveResult(new ResolveResult(delegateType), invokeMethod, EmptyList<ResolveResult>.Instance); rr = new CSharpInvocationResolveResult(
new ResolveResult(delegateType),
invokeMethod,
EmptyList<ResolveResult>.Instance);
} }
return new InvocationExpression(new MemberReferenceExpression(invocationTarget, "Invoke")) return new InvocationExpression(new MemberReferenceExpression(invocationTarget, "Invoke"))
.WithILInstruction(container) .WithILInstruction(container)

Loading…
Cancel
Save