Browse Source

Fix #2120: An expression tree may not contain a base access

pull/2126/head
Siegfried Pammer 5 years ago
parent
commit
55842e4bfc
  1. 13
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 19
      ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs

13
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -2061,7 +2061,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2061,7 +2061,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 && MatchLdThis(target) && memberDeclaringType.GetDefinition() != resolver.CurrentTypeDefinition) {
if (ShouldUseBaseReference()) {
return new BaseReferenceExpression()
.WithILInstruction(target)
.WithRR(new ThisResolveResult(memberDeclaringType, nonVirtualInvocation));
@ -2097,6 +2097,17 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2097,6 +2097,17 @@ namespace ICSharpCode.Decompiler.CSharp
.WithRR(new TypeResolveResult(memberDeclaringType));
}
bool ShouldUseBaseReference()
{
if (!nonVirtualInvocation)
return false;
if (!MatchLdThis(target))
return false;
if (memberDeclaringType.GetDefinition() == resolver.CurrentTypeDefinition)
return false;
return true;
}
bool MatchLdThis(ILInstruction inst)
{
// ldloc this

19
ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs

@ -512,7 +512,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -512,7 +512,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
switch (member) {
case IMethod method:
if (method.IsStatic)
return (targetVariable => new Call(method) { Arguments = { new LdLoc(targetVariable), value() } }, method.ReturnType);
else
return (targetVariable => new CallVirt(method) { Arguments = { new LdLoc(targetVariable), value() } }, method.ReturnType);
case IField field:
return (targetVariable => new StObj(new LdFlda(new LdLoc(targetVariable), (IField)member) { DelayExceptions = true }, value(), member.ReturnType), field.ReturnType);
}
@ -560,10 +563,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -560,10 +563,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
CallInstruction BuildCall()
{
CallInstruction call;
if (method.IsAbstract || method.IsVirtual || method.IsOverride) {
call = new CallVirt(method);
} else {
if (method.IsStatic) {
call = new Call(method);
} else {
call = new CallVirt(method);
}
if (targetConverter != null) {
call.Arguments.Add(PrepareCallTarget(method.DeclaringType, targetConverter(), targetType));
@ -749,7 +752,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -749,7 +752,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ILInstruction BuildCall()
{
CallInstruction call = new Call((IMethod)member);
CallInstruction call = member.IsStatic
? (CallInstruction)new Call((IMethod)member)
: new CallVirt((IMethod)member);
call.Arguments.AddRange(args.Select(f => f()));
return call;
}
@ -1123,10 +1128,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -1123,10 +1128,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ILInstruction BuildProperty()
{
CallInstruction call;
if (member.IsAbstract || member.IsVirtual || member.IsOverride) {
call = new CallVirt((IMethod)member);
} else {
if (member.IsStatic) {
call = new Call((IMethod)member);
} else {
call = new CallVirt((IMethod)member);
}
if (targetConverter != null) {
call.Arguments.Add(PrepareCallTarget(member.DeclaringType, targetConverter(), targetType));

Loading…
Cancel
Save