DFA: support of arithmetic no-ops (*1, /1, >>0, etc.)

This commit is contained in:
Tagir Valeev
2019-01-14 09:43:19 +07:00
parent 997d65caac
commit e652cc3b6f
3 changed files with 38 additions and 0 deletions
@@ -95,6 +95,16 @@ public class DfaBinOpValue extends DfaValue {
}
LongRangeSet leftRange = state.getValueFact(left, DfaFactType.RANGE);
LongRangeSet rightRange = state.getValueFact(right, DfaFactType.RANGE);
if (tokenType.equals(JavaTokenType.ASTERISK)) {
if (LongRangeSet.point(1).equals(leftRange)) return right;
if (LongRangeSet.point(1).equals(rightRange)) return left;
}
if (tokenType.equals(JavaTokenType.DIV)) {
if (LongRangeSet.point(1).equals(rightRange)) return left;
}
if (tokenType.equals(JavaTokenType.GTGT) || tokenType.equals(JavaTokenType.LTLT) || tokenType.equals(JavaTokenType.GTGTGT)) {
if (LongRangeSet.point(0).equals(rightRange)) return left;
}
if (leftRange != null && rightRange != null) {
LongRangeSet result = leftRange.binOpFromToken(tokenType, rightRange, isLong);
return myFactory.getFactValue(DfaFactType.RANGE, result);
@@ -0,0 +1,27 @@
import java.util.*;
public class ArithmeticNoOp {
void test(long x, int y) {
if(y == 1) {
long z = x * y;
long t = x / y;
long u = y / z;
long w = y * z;
if (<warning descr="Condition 'z == x' is always 'true'">z == x</warning>) {}
if (<warning descr="Condition 't == x' is always 'true'">t == x</warning>) {}
if (<warning descr="Condition 'w == x' is always 'true'">w == x</warning>) {}
if (u == x) {}
}
if(y == 0) {
long a = x >> y;
long b = x << y;
long c = x >>> y;
long d = y >>> x;
if (<warning descr="Condition 'a == x' is always 'true'">a == x</warning>) {}
if (<warning descr="Condition 'b == x' is always 'true'">b == x</warning>) {}
if (<warning descr="Condition 'c == x' is always 'true'">c == x</warning>) {}
if (d == x) {}
if (<warning descr="Condition 'd == y' is always 'true'">d == y</warning>) {}
}
}
}
@@ -60,4 +60,5 @@ public class DataFlowRangeAnalysisTest extends DataFlowInspectionTestCase {
public void testTwoArraysDiff() { doTest(); }
public void testModRange() { doTest(); }
public void testBackPropagationMod() { doTest(); }
public void testArithmeticNoOp() { doTest(); }
}