diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs index fc7fa41ba..fdc138546 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs @@ -155,6 +155,49 @@ namespace ICSharpCode.Decompiler.Tests.Pretty } } + public class Root + { + private int prop; + +#if LEGACY_CSC + public int Prop { + get { + return prop; + } + } +#else + public int Prop => prop; +#endif + public void M(T a) + { + + } + } + + public abstract class Base : Root + { + public new abstract int Prop { get; } + + public new abstract void M(T a); + } + + public class Derived : Base + { +#if LEGACY_CSC + public override int Prop { + get { + return ((Root)this).Prop; + } + } +#else + public override int Prop => ((Root)this).Prop; +#endif + public override void M(T a) + { + ((Root)this).M(a); + } + } + private int fieldConflict; private int innerConflict; diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index ae4f23486..29fab54b6 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -2487,9 +2487,11 @@ namespace ICSharpCode.Decompiler.CSharp { if (ShouldUseBaseReference()) { + var baseReferenceType = resolver.CurrentTypeDefinition.DirectBaseTypes + .FirstOrDefault(t => t.Kind != TypeKind.Interface); return new BaseReferenceExpression() .WithILInstruction(target) - .WithRR(new ThisResolveResult(memberDeclaringType, nonVirtualInvocation)); + .WithRR(new ThisResolveResult(baseReferenceType ?? memberDeclaringType, nonVirtualInvocation)); } else { diff --git a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs index f64dc39a4..71605ce06 100644 --- a/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs +++ b/ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs @@ -452,6 +452,7 @@ namespace ICSharpCode.Decompiler.CSharp // perform remaining pointer cast, if necessary return pointerExpr.ConvertTo(targetType, expressionBuilder); } + Expression expr; if (targetType.Kind == TypeKind.ByReference) { if (NormalizeTypeVisitor.TypeErasure.EquivalentTypes(targetType, this.Type)) @@ -481,7 +482,6 @@ namespace ICSharpCode.Decompiler.CSharp // Convert from integer/pointer to reference. // First, convert to the corresponding pointer type: var arg = this.ConvertTo(new PointerType(elementType), expressionBuilder, checkForOverflow); - Expression expr; ResolveResult elementRR; if (arg.Expression is UnaryOperatorExpression unary && unary.Operator == UnaryOperatorType.AddressOf) { @@ -561,7 +561,11 @@ namespace ICSharpCode.Decompiler.CSharp return this; } } - var castExpr = new CastExpression(expressionBuilder.ConvertType(targetType), Expression); + // BaseReferenceExpression must not be used with CastExpressions + expr = Expression is BaseReferenceExpression + ? new ThisReferenceExpression().WithILInstruction(this.ILInstructions) + : Expression; + var castExpr = new CastExpression(expressionBuilder.ConvertType(targetType), expr); bool needsCheckAnnotation = targetUType.GetStackType().IsIntegerType(); if (needsCheckAnnotation) {