Browse Source

Fix compound assignments with type `bool`.

This required removing the "Replace bit.and with logic.and" transform, as it interfered with the compound assignment transform.
pull/1835/head
Daniel Grunwald 6 years ago
parent
commit
93806b46fa
  1. 22
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs
  2. 5
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  3. 10
      ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

22
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs

@ -60,6 +60,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
get; get;
set; set;
} }
public bool BoolProperty {
get;
set;
}
public uint this[string name] { public uint this[string name] {
get { get {
@ -802,6 +807,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return M().ByteProperty *= 2; return M().ByteProperty *= 2;
} }
public void BitManipBoolProperty(bool b)
{
M().BoolProperty |= b;
M().BoolProperty &= b;
M().BoolProperty ^= b;
}
public bool BitOrBoolPropertyAndReturn(bool b)
{
return M().BoolProperty |= b;
}
public bool BitAndBoolPropertyAndReturn(bool b)
{
return M().BoolProperty &= b;
}
public int PreIncrementStaticField() public int PreIncrementStaticField()
{ {
return ++StaticField; return ++StaticField;

5
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -679,11 +679,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
if (new NullableLiftingTransform(context).Run(inst)) { if (new NullableLiftingTransform(context).Run(inst)) {
// e.g. "(a.GetValueOrDefault() == b.GetValueOrDefault()) & (a.HasValue & b.HasValue)" // e.g. "(a.GetValueOrDefault() == b.GetValueOrDefault()) & (a.HasValue & b.HasValue)"
} else if (SemanticHelper.IsPure(inst.Right.Flags)) {
context.Step("Replace bit.and with logic.and", inst);
var expr = IfInstruction.LogicAnd(inst.Left, inst.Right);
inst.ReplaceWith(expr);
expr.AcceptVisitor(this);
} }
} }
break; break;

10
ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

@ -459,6 +459,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return conv.TargetType != type.ToPrimitiveType(); return conv.TargetType != type.ToPrimitiveType();
} else if (value is Comp) { } else if (value is Comp) {
return false; // comp returns 0 or 1, which always fits return false; // comp returns 0 or 1, which always fits
} else if (value is BinaryNumericInstruction bni) {
switch (bni.Operator) {
case BinaryNumericOperator.BitAnd:
case BinaryNumericOperator.BitOr:
case BinaryNumericOperator.BitXor:
// If both input values fit into the type without truncation,
// the result of a binary operator will also fit.
return IsImplicitTruncation(bni.Left, type, compilation, allowNullableValue)
|| IsImplicitTruncation(bni.Right, type, compilation, allowNullableValue);
}
} else if (value is IfInstruction ifInst) { } else if (value is IfInstruction ifInst) {
return IsImplicitTruncation(ifInst.TrueInst, type, compilation, allowNullableValue) return IsImplicitTruncation(ifInst.TrueInst, type, compilation, allowNullableValue)
|| IsImplicitTruncation(ifInst.FalseInst, type, compilation, allowNullableValue); || IsImplicitTruncation(ifInst.FalseInst, type, compilation, allowNullableValue);

Loading…
Cancel
Save