Browse Source

Merge pull request #2315 from icsharpcode/fix-1828

Ensure base references have the correct type
pull/2316/head
Daniel Grunwald 4 years ago committed by GitHub
parent
commit
f286ddb952
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 43
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs
  2. 4
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  3. 8
      ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

43
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>(T a)
{
}
}
public abstract class Base : Root
{
public new abstract int Prop { get; }
public new abstract void M<T>(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>(T a)
{
((Root)this).M(a);
}
}
private int fieldConflict; private int fieldConflict;
private int innerConflict; private int innerConflict;

4
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -2487,9 +2487,11 @@ namespace ICSharpCode.Decompiler.CSharp
{ {
if (ShouldUseBaseReference()) if (ShouldUseBaseReference())
{ {
var baseReferenceType = resolver.CurrentTypeDefinition.DirectBaseTypes
.FirstOrDefault(t => t.Kind != TypeKind.Interface);
return new BaseReferenceExpression() return new BaseReferenceExpression()
.WithILInstruction(target) .WithILInstruction(target)
.WithRR(new ThisResolveResult(memberDeclaringType, nonVirtualInvocation)); .WithRR(new ThisResolveResult(baseReferenceType ?? memberDeclaringType, nonVirtualInvocation));
} }
else else
{ {

8
ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

@ -452,6 +452,7 @@ namespace ICSharpCode.Decompiler.CSharp
// perform remaining pointer cast, if necessary // perform remaining pointer cast, if necessary
return pointerExpr.ConvertTo(targetType, expressionBuilder); return pointerExpr.ConvertTo(targetType, expressionBuilder);
} }
Expression expr;
if (targetType.Kind == TypeKind.ByReference) if (targetType.Kind == TypeKind.ByReference)
{ {
if (NormalizeTypeVisitor.TypeErasure.EquivalentTypes(targetType, this.Type)) if (NormalizeTypeVisitor.TypeErasure.EquivalentTypes(targetType, this.Type))
@ -481,7 +482,6 @@ namespace ICSharpCode.Decompiler.CSharp
// Convert from integer/pointer to reference. // Convert from integer/pointer to reference.
// First, convert to the corresponding pointer type: // First, convert to the corresponding pointer type:
var arg = this.ConvertTo(new PointerType(elementType), expressionBuilder, checkForOverflow); var arg = this.ConvertTo(new PointerType(elementType), expressionBuilder, checkForOverflow);
Expression expr;
ResolveResult elementRR; ResolveResult elementRR;
if (arg.Expression is UnaryOperatorExpression unary && unary.Operator == UnaryOperatorType.AddressOf) if (arg.Expression is UnaryOperatorExpression unary && unary.Operator == UnaryOperatorType.AddressOf)
{ {
@ -561,7 +561,11 @@ namespace ICSharpCode.Decompiler.CSharp
return this; 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(); bool needsCheckAnnotation = targetUType.GetStackType().IsIntegerType();
if (needsCheckAnnotation) if (needsCheckAnnotation)
{ {

Loading…
Cancel
Save