From ab993fc6c60ef4961e051ffa24ffaf227a0c5847 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 23 Aug 2019 23:10:31 +0200 Subject: [PATCH] Fix invalid code generated for impossible casts. --- .../TestCases/Pretty/TypeAnalysisTests.cs | 10 ++++++++++ ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.cs index 118e2a144..2993b179a 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.cs @@ -276,5 +276,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { return AttributeTargets.All.HasFlag(AttributeTargets.Assembly); } + + public static string ImpossibleCast1(int i) + { + return (string)(object)i; + } + + public static string ImpossibleCast2(Action a) + { + return (string)(object)a; + } } } diff --git a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs index 35582ec1d..6a467ea13 100644 --- a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs +++ b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs @@ -416,6 +416,13 @@ namespace ICSharpCode.Decompiler.CSharp if (rr.IsCompileTimeConstant && !rr.IsError) { return expressionBuilder.ConvertConstantValue(rr, allowImplicitConversion) .WithILInstruction(this.ILInstructions); + } else if (rr.IsError && targetType.IsReferenceType == true && type.IsReferenceType == true) { + // Conversion between two reference types, but no direct cast allowed? cast via object + // Just make sure we avoid infinite recursion even if the resolver falsely claims we can't cast directly: + if (!(targetType.IsKnownType(KnownTypeCode.Object) || type.IsKnownType(KnownTypeCode.Object))) { + return this.ConvertTo(compilation.FindType(KnownTypeCode.Object), expressionBuilder) + .ConvertTo(targetType, expressionBuilder, checkForOverflow, allowImplicitConversion); + } } if (targetType.Kind == TypeKind.Pointer && (0.Equals(ResolveResult.ConstantValue) || 0u.Equals(ResolveResult.ConstantValue))) { if (allowImplicitConversion) {