Browse Source

Fix #1955: struct 'base' access to ValueType mis-decompiles

pull/1968/head
Siegfried Pammer 5 years ago
parent
commit
7c7328df32
  1. 11
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs
  2. 20
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

11
ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs

@ -74,6 +74,17 @@ namespace ICSharpCode.Decompiler.Tests.Pretty @@ -74,6 +74,17 @@ namespace ICSharpCode.Decompiler.Tests.Pretty
{
}
public string ThisQualifierWithCast()
{
return ((object)this).ToString();
}
public override string ToString()
{
// decompiled as return ((ValueType)this).ToString();
return base.ToString();
}
}
internal class Parent

20
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1999,7 +1999,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1999,7 +1999,7 @@ namespace ICSharpCode.Decompiler.CSharp
// If references are missing member.IsStatic might not be set correctly.
// Additionally check target for null, in order to avoid a crash.
if (!memberStatic && target != null) {
if (nonVirtualInvocation && target.MatchLdThis() && memberDeclaringType.GetDefinition() != resolver.CurrentTypeDefinition) {
if (nonVirtualInvocation && MatchLdThis(target) && memberDeclaringType.GetDefinition() != resolver.CurrentTypeDefinition) {
return new BaseReferenceExpression()
.WithILInstruction(target)
.WithRR(new ThisResolveResult(memberDeclaringType, nonVirtualInvocation));
@ -2034,6 +2034,24 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2034,6 +2034,24 @@ namespace ICSharpCode.Decompiler.CSharp
.WithoutILInstruction()
.WithRR(new TypeResolveResult(memberDeclaringType));
}
bool MatchLdThis(ILInstruction inst)
{
// ldloc this
if (inst.MatchLdThis())
return true;
if (resolver.CurrentTypeDefinition.Kind == TypeKind.Struct) {
// box T(ldobj T(ldloc this))
if (!inst.MatchBox(out var arg, out var type))
return false;
if (!arg.MatchLdObj(out var arg2, out var type2))
return false;
if (!type.Equals(type2) || !type.Equals(resolver.CurrentTypeDefinition))
return false;
return arg2.MatchLdThis();
}
return false;
}
}
private TranslatedExpression EnsureTargetNotNullable(TranslatedExpression expr)

Loading…
Cancel
Save