From f66ccea9ef98131d36ce8befc2e83ba70b827b93 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 6 Oct 2024 12:02:16 +0200 Subject: [PATCH] Fix #3296: Ensure unknown types are wrapped properly in "Convert Expression Tree" --- .../IL/Transforms/TransformExpressionTrees.cs | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs index 81632f6a5..2f4121b2a 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs @@ -642,37 +642,51 @@ namespace ICSharpCode.Decompiler.IL.Transforms ILInstruction PrepareCallTarget(IType expectedType, ILInstruction target, IType targetType) { + ILInstruction result; switch (CallInstruction.ExpectedTypeForThisPointer(expectedType)) { case StackType.Ref: if (target.ResultType == StackType.Ref) { - return target; + result = target; } else if (target is LdLoc ldloc) { - return new LdLoca(ldloc.Variable).WithILRange(ldloc); + result = new LdLoca(ldloc.Variable).WithILRange(ldloc); } else { - return new AddressOf(target, expectedType); + result = new AddressOf(target, expectedType); } + break; case StackType.O: if (targetType.IsReferenceType == false) { - return new Box(target, targetType); + result = new Box(target, targetType); } else { - return target; + result = target; } + break; default: - if (expectedType.Kind == TypeKind.Unknown && target.ResultType != StackType.Unknown) - { - return new Conv(target, PrimitiveType.Unknown, false, Sign.None); - } - return target; + result = target; + break; } + + if (expectedType.Kind == TypeKind.Unknown && result.ResultType != StackType.Unknown) + { + result = new Conv(target, PrimitiveType.Unknown, false, Sign.None); + } + else if (expectedType.Kind != TypeKind.Unknown && result.ResultType == StackType.Unknown) + { + // if references are missing, we need to coerce the unknown type to the expected type. + // Otherwise we will get loads of assertions and expression trees + // are usually explicit about any conversions. + result = new Conv(result, expectedType.ToPrimitiveType(), false, Sign.None); + } + + return result; } ILInstruction UnpackConstant(ILInstruction inst)