[java-dfa] DfaBinOpValue: math during backpropagation should be done within the required type

Otherwise, we can get the wrong number due to non-processed overflow when negating (for x-Integer.MIN_VALUE) or when collapsing two bin-ops into one
Fixes EA-290247 - IAE: DfaBinOpValue.<init>

GitOrigin-RevId: 2390830de3b91fb0f6390b75558e565e4fc73a45
This commit is contained in:
Tagir Valeev
2021-06-25 11:42:16 +00:00
committed by intellij-monorepo-bot
parent 61bf6f49a8
commit 3ca2ad32e0
2 changed files with 12 additions and 6 deletions
@@ -135,4 +135,9 @@ public class BackPropagation {
}
return x * 2;
}
public void backPropagationMinValue(int x) {
if (<warning descr="Condition 'x - Integer.MIN_VALUE == x + Integer.MIN_VALUE' is always 'true'">x - Integer.MIN_VALUE == x + Integer.MIN_VALUE</warning>) {}
if (<warning descr="Condition 'x - 2_000_000_000 - 2_000_000_000 == x + 294967296' is always 'true'">x - 2_000_000_000 - 2_000_000_000 == x + 294967296</warning>) {}
}
}
@@ -186,7 +186,7 @@ public final class DfaBinOpValue extends DfaValue {
long value = rightConst.longValue();
if (value == 0) return left;
if (op == LongRangeBinOp.MINUS) {
right = myFactory.fromDfType(resultType.meetRange(LongRangeSet.point(-value)));
right = myFactory.fromDfType(resultType.meetRange(LongRangeSet.point(value).negate(resultType.getLongRangeType())));
}
return doCreate((DfaVariableValue)left, right, resultType, LongRangeBinOp.PLUS);
}
@@ -196,13 +196,14 @@ public final class DfaBinOpValue extends DfaValue {
if (sumValue.getOperation() != LongRangeBinOp.PLUS && sumValue.getOperation() != LongRangeBinOp.MINUS) return null;
if (rightConst != null) {
if (sumValue.getRight() instanceof DfaTypeValue) {
long value1 = extractLong((DfaTypeValue)sumValue.getRight());
long value2 = rightConst.longValue();
DfType rightType = sumValue.getRight().getDfType();
LongRangeSet value1 = ((DfIntegralType)rightType).getRange();
LongRangeSet value2 = LongRangeSet.point(rightConst.longValue());
if (op == LongRangeBinOp.MINUS) {
value2 = -value2;
value2 = value2.negate(resultType.getLongRangeType());
}
long res = value1 + value2;
right = myFactory.fromDfType(resultType.meetRange(LongRangeSet.point(res)));
LongRangeSet res = value1.plus(value2, resultType.getLongRangeType());
right = myFactory.fromDfType(resultType.meetRange(res));
return create(sumValue.getLeft(), right, state, resultType, LongRangeBinOp.PLUS);
}
}