Browse Source

Fix HandleCompoundAssignment

pull/728/merge
Siegfried Pammer 9 years ago
parent
commit
d5366140d8
  1. 40
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

40
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -672,32 +672,44 @@ namespace ICSharpCode.Decompiler.CSharp @@ -672,32 +672,44 @@ namespace ICSharpCode.Decompiler.CSharp
TranslatedExpression HandleCompoundAssignment(CompoundAssignmentInstruction inst, AssignmentOperatorType op)
{
var resolverWithOverflowCheck = resolver.WithCheckForOverflow(inst.CheckForOverflow);
var target = Translate(inst.Target);
var value = Translate(inst.Value);
value = PrepareArithmeticArgument(value, inst.Value.ResultType, inst.Sign);
var rr = resolverWithOverflowCheck.ResolveAssignment(op, target.ResolveResult, value.ResolveResult);
if (rr.IsError || rr.Type.GetStackType() != inst.ResultType
|| !IsCompatibleWithSign(target.Type, inst.Sign) || !IsCompatibleWithSign(value.Type, inst.Sign))
{
// Target and value are incompatible, so convert value to the target type
// inst.ResultType should match inst.Target.ResultType
Debug.Assert(inst.ResultType == inst.Target.ResultType);
value = value.ConvertTo(inst.Type, this);
rr = resolverWithOverflowCheck.ResolveAssignment(op, target.ResolveResult, value.ResolveResult);
}
TranslatedExpression resultExpr;
if (inst.CompoundAssignmentType == CompoundAssignmentType.EvaluatesToOldValue) {
Debug.Assert(op == AssignmentOperatorType.Add || op == AssignmentOperatorType.Subtract);
Debug.Assert(value.ResolveResult.IsCompileTimeConstant && 1.Equals(value.ResolveResult.ConstantValue));
resultExpr = new UnaryOperatorExpression(op == AssignmentOperatorType.Add ? UnaryOperatorType.PostIncrement : UnaryOperatorType.PostDecrement, target)
UnaryOperatorType unary;
ExpressionType exprType;
if (op == AssignmentOperatorType.Add) {
unary = UnaryOperatorType.PostIncrement;
exprType = ExpressionType.PostIncrementAssign;
} else {
unary = UnaryOperatorType.PostDecrement;
exprType = ExpressionType.PostDecrementAssign;
}
resultExpr = new UnaryOperatorExpression(unary, target)
.WithILInstruction(inst)
.WithRR(rr);
.WithRR(new OperatorResolveResult(target.Type, exprType, target.ResolveResult));
} else {
switch (op) {
case AssignmentOperatorType.Add:
case AssignmentOperatorType.Subtract:
value = value.ConvertTo(target.Type.GetEnumUnderlyingType(), this, inst.CheckForOverflow);
break;
case AssignmentOperatorType.Multiply:
case AssignmentOperatorType.Divide:
case AssignmentOperatorType.Modulus:
case AssignmentOperatorType.BitwiseAnd:
case AssignmentOperatorType.BitwiseOr:
case AssignmentOperatorType.ExclusiveOr:
value = value.ConvertTo(target.Type, this, inst.CheckForOverflow);
break;
}
resultExpr = new AssignmentExpression(target.Expression, op, value.Expression)
.WithILInstruction(inst)
.WithRR(rr);
.WithRR(new OperatorResolveResult(target.Type, AssignmentExpression.GetLinqNodeType(op, inst.CheckForOverflow), target.ResolveResult, value.ResolveResult));
}
if (AssignmentOperatorMightCheckForOverflow(op))
resultExpr.Expression.AddAnnotation(inst.CheckForOverflow ? AddCheckedBlocks.CheckedAnnotation : AddCheckedBlocks.UncheckedAnnotation);

Loading…
Cancel
Save