Browse Source

Fix #1053: virtual protected base method with 'out', invalid cast-to-base on use.

pull/1072/merge
Siegfried Pammer 7 years ago
parent
commit
3892762e70
  1. 8
      ICSharpCode.Decompiler/CSharp/CallBuilder.cs
  2. 15
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  3. 3
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

8
ICSharpCode.Decompiler/CSharp/CallBuilder.cs

@ -128,8 +128,14 @@ namespace ICSharpCode.Decompiler.CSharp @@ -128,8 +128,14 @@ namespace ICSharpCode.Decompiler.CSharp
arguments.Add(arg.ConvertTo(parameter.Type, expressionBuilder, allowImplicitConversion: true));
if (parameter.IsOut && arguments[i].Expression is DirectionExpression dirExpr) {
if (parameter.IsOut && arguments[i].Expression is DirectionExpression dirExpr && arguments[i].ResolveResult is ByReferenceResolveResult brrr) {
dirExpr.FieldDirection = FieldDirection.Out;
dirExpr.RemoveAnnotations<ByReferenceResolveResult>();
if (brrr.ElementResult == null)
brrr = new ByReferenceResolveResult(brrr.ElementType, isOut: true);
else
brrr = new ByReferenceResolveResult(brrr.ElementResult, isOut: true);
dirExpr.AddAnnotation(brrr);
}
}

15
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -179,7 +179,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -179,7 +179,7 @@ namespace ICSharpCode.Decompiler.CSharp
expr.WithRR(new ILVariableResolveResult(variable, elementType));
expr = new DirectionExpression(FieldDirection.Ref, expr);
return expr.WithRR(new ResolveResult(variable.Type));
return expr.WithRR(new ByReferenceResolveResult(elementType, isOut: false));
} else {
return expr.WithRR(new ILVariableResolveResult(variable, variable.Type));
}
@ -1649,7 +1649,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1649,7 +1649,7 @@ namespace ICSharpCode.Decompiler.CSharp
} else {
// ldflda producing managed pointer
return new DirectionExpression(FieldDirection.Ref, expr)
.WithoutILInstruction().WithRR(new ResolveResult(new ByReferenceType(expr.Type)));
.WithoutILInstruction().WithRR(new ByReferenceResolveResult(expr.Type, isOut: false));
}
}
@ -1657,7 +1657,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1657,7 +1657,7 @@ namespace ICSharpCode.Decompiler.CSharp
{
var expr = ConvertField(inst.Field).WithILInstruction(inst);
return new DirectionExpression(FieldDirection.Ref, expr)
.WithoutILInstruction().WithRR(new ResolveResult(new ByReferenceType(expr.Type)));
.WithoutILInstruction().WithRR(new ByReferenceResolveResult(expr.Type, isOut: false));
}
protected internal override TranslatedExpression VisitLdElema(LdElema inst, TranslationContext context)
@ -1672,7 +1672,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1672,7 +1672,7 @@ namespace ICSharpCode.Decompiler.CSharp
arrayExpr, inst.Indices.Select(i => TranslateArrayIndex(i).Expression)
).WithILInstruction(inst).WithRR(new ResolveResult(arrayType.ElementType));
return new DirectionExpression(FieldDirection.Ref, expr)
.WithoutILInstruction().WithRR(new ResolveResult(new ByReferenceType(expr.Type)));
.WithoutILInstruction().WithRR(new ByReferenceResolveResult(expr.Type, isOut: false));
}
TranslatedExpression TranslateArrayIndex(ILInstruction i)
@ -1720,7 +1720,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1720,7 +1720,7 @@ namespace ICSharpCode.Decompiler.CSharp
.WithRR(new ConversionResolveResult(inst.Type, arg.ResolveResult, Conversion.UnboxingConversion));
return new DirectionExpression(FieldDirection.Ref, castExpression)
.WithILInstruction(inst)
.WithRR(new ConversionResolveResult(new ByReferenceType(inst.Type), arg.ResolveResult, Conversion.UnboxingConversion));
.WithRR(new ByReferenceResolveResult(castExpression.ResolveResult, isOut: false));
}
protected internal override TranslatedExpression VisitBox(Box inst, TranslationContext context)
@ -2111,11 +2111,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2111,11 +2111,12 @@ namespace ICSharpCode.Decompiler.CSharp
if (rr.Type.Kind == TypeKind.ByReference) {
// C# conditional ref looks like this:
// ref (arr != null ? ref trueBranch : ref falseBranch);
var conditionalResolveResult = new ResolveResult(((ByReferenceType)rr.Type).ElementType);
return new DirectionExpression(FieldDirection.Ref,
new ConditionalExpression(condition.Expression, trueBranch.Expression, falseBranch.Expression)
.WithILInstruction(inst)
.WithRR(new ResolveResult(((ByReferenceType)rr.Type).ElementType))
).WithoutILInstruction().WithRR(rr);
.WithRR(conditionalResolveResult)
).WithoutILInstruction().WithRR(new ByReferenceResolveResult(conditionalResolveResult, isOut: false));
} else {
return new ConditionalExpression(condition.Expression, trueBranch.Expression, falseBranch.Expression)
.WithILInstruction(inst)

3
ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

@ -616,8 +616,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -616,8 +616,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
new AssignmentExpression {
Left = new IdentifierExpressionBackreference("var1"),
Right = new InvocationExpression(new MemberReferenceExpression(new TypeReferenceExpression(new TypePattern(typeof(System.Threading.Interlocked)).ToType()),
"CompareExchange",
new AstType[] { new Backreference("type") }), // type argument
"CompareExchange"),
new Expression[] { // arguments
new DirectionExpression { FieldDirection = FieldDirection.Ref, Expression = new Backreference("field") },
new IdentifierExpressionBackreference("var3"),

Loading…
Cancel
Save