diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
index 29262da59..c0617cbef 100644
--- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
+++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
@@ -639,9 +639,7 @@ namespace ICSharpCode.Decompiler.CSharp
// 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);
- StackType targetStackType = inst.ResultType == StackType.I ? StackType.I8 : inst.ResultType;
- IType targetType = compilation.FindType(targetStackType.ToKnownTypeCode(inst.Sign));
- value = value.ConvertTo(targetType, this);
+ value = value.ConvertTo(inst.Type, this);
rr = resolverWithOverflowCheck.ResolveAssignment(op, target.ResolveResult, value.ResolveResult);
}
TranslatedExpression resultExpr;
diff --git a/ICSharpCode.Decompiler/IL/Instructions.cs b/ICSharpCode.Decompiler/IL/Instructions.cs
index 19d7ec780..3d9226f82 100644
--- a/ICSharpCode.Decompiler/IL/Instructions.cs
+++ b/ICSharpCode.Decompiler/IL/Instructions.cs
@@ -788,7 +788,10 @@ namespace ICSharpCode.Decompiler.IL
clone.Value = this.value.Clone();
return clone;
}
- public override StackType ResultType { get { return target.ResultType; } }
+ readonly IType type;
+ /// Returns the type operand.
+ public IType Type { get { return type; } }
+ public override StackType ResultType { get { return type.GetStackType(); } }
public override void AcceptVisitor(ILVisitor visitor)
{
visitor.VisitCompoundAssignmentInstruction(this);
diff --git a/ICSharpCode.Decompiler/IL/Instructions.tt b/ICSharpCode.Decompiler/IL/Instructions.tt
index 3b868b4fa..c632a22e2 100644
--- a/ICSharpCode.Decompiler/IL/Instructions.tt
+++ b/ICSharpCode.Decompiler/IL/Instructions.tt
@@ -62,7 +62,7 @@
CustomClassName("BinaryNumericInstruction"), Binary, CustomWriteTo, CustomConstructor, CustomComputeFlags),
new OpCode("compound", "Common instruction for compound assignments.",
CustomClassName("CompoundAssignmentInstruction"), CustomConstructor, CustomComputeFlags,
- MayThrow, CustomArguments("target", "value"), ResultType("target.ResultType"), CustomWriteTo),
+ MayThrow, CustomArguments("target", "value"), HasTypeOperand, ResultType("type.GetStackType()"), CustomWriteTo),
new OpCode("bit.not", "Bitwise NOT", Unary),
new OpCode("arglist", "Retrieves the RuntimeArgumentHandle.", NoArguments, ResultType("O")),
new OpCode("br", "Unconditional branch. goto target;",
diff --git a/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs
index b78fa11b1..ca9a3ac89 100644
--- a/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs
+++ b/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs
@@ -51,13 +51,14 @@ namespace ICSharpCode.Decompiler.IL
public readonly CompoundAssignmentType CompoundAssignmentType;
- public CompoundAssignmentInstruction(BinaryNumericOperator op, ILInstruction target, ILInstruction value, bool checkForOverflow, Sign sign, CompoundAssignmentType compoundAssigmentType)
+ public CompoundAssignmentInstruction(BinaryNumericOperator op, ILInstruction target, ILInstruction value, IType type, bool checkForOverflow, Sign sign, CompoundAssignmentType compoundAssigmentType)
: base(OpCode.CompoundAssignmentInstruction)
{
this.CheckForOverflow = checkForOverflow;
this.Sign = sign;
this.Operator = op;
this.Target = target;
+ this.type = type;
this.Value = value;
this.CompoundAssignmentType = compoundAssigmentType;
Debug.Assert(compoundAssigmentType == CompoundAssignmentType.EvaluatesToNewValue || (op == BinaryNumericOperator.Add || op == BinaryNumericOperator.Sub));
diff --git a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
index 1dd745931..29149b4cd 100644
--- a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
+++ b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
@@ -195,7 +195,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (binary != null && binary.Left.MatchLdObj(out target, out t) && IsSameTarget(inst.Target, target)) {
// stobj(target, binary.op(ldobj(target), ...))
// => compound.op(target, ...)
- inst.ReplaceWith(new CompoundAssignmentInstruction(binary.Operator, binary.Left, binary.Right, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToNewValue));
+ inst.ReplaceWith(new CompoundAssignmentInstruction(binary.Operator, binary.Left, binary.Right, t, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToNewValue));
}
}
diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs
index 75b72481e..b18127d02 100644
--- a/ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs
+++ b/ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs
@@ -206,7 +206,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (binary == null || !binary.Left.MatchLdLoc(nextInst.Variable) || !binary.Right.MatchLdcI4(1)
|| (binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub))
return false;
- var assignment = new CompoundAssignmentInstruction(binary.Operator, new LdObj(inst.Value, targetType), binary.Right, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToOldValue);
+ var assignment = new CompoundAssignmentInstruction(binary.Operator, new LdObj(inst.Value, targetType), binary.Right, targetType, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToOldValue);
stobj.ReplaceWith(new StLoc(nextInst.Variable, assignment));
block.Instructions.RemoveAt(i + 1);
return true;
@@ -255,7 +255,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (binary == null || !binary.Left.MatchLdLoc(fieldValue.Variable) || !binary.Right.MatchLdcI4(1)
|| (binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub))
return false;
- var assignment = new CompoundAssignmentInstruction(binary.Operator, new LdObj(baseAddress, t), binary.Right, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToOldValue);
+ var assignment = new CompoundAssignmentInstruction(binary.Operator, new LdObj(baseAddress, t), binary.Right, t, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToOldValue);
stobj.ReplaceWith(new StLoc(fieldValueCopyToLocal.Variable, assignment));
block.Instructions.RemoveAt(i + 2);
block.Instructions.RemoveAt(i + 1);