Skip to content

Commit 61b3458

Browse files
committed
Java: Refactor integerGuard.
1 parent 05fcceb commit 61b3458

File tree

1 file changed

+56
-65
lines changed

1 file changed

+56
-65
lines changed

java/ql/lib/semmle/code/java/dataflow/IntegerGuards.qll

Lines changed: 56 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,58 @@ class IntComparableExpr extends Expr {
3232
}
3333
}
3434

35+
/**
36+
* Holds if `comp` evaluating to `branch` ensures that `e1` is less than `e2`.
37+
* When `strict` is true, `e1` is strictly less than `e2`, otherwise it is less
38+
* than or equal to `e2`.
39+
*/
40+
private predicate comparison(ComparisonExpr comp, boolean branch, Expr e1, Expr e2, boolean strict) {
41+
branch = true and
42+
e1 = comp.getLesserOperand() and
43+
e2 = comp.getGreaterOperand() and
44+
(if comp.isStrict() then strict = true else strict = false)
45+
or
46+
branch = false and
47+
e1 = comp.getGreaterOperand() and
48+
e2 = comp.getLesserOperand() and
49+
(if comp.isStrict() then strict = false else strict = true)
50+
}
51+
52+
/**
53+
* Holds if `guard` evaluating to `branch` ensures that:
54+
* `e <= k` when `upper = true`
55+
* `e >= k` when `upper = false`
56+
*/
57+
pragma[nomagic]
58+
predicate rangeGuard(Expr guard, boolean branch, Expr e, int k, boolean upper) {
59+
exists(EqualityTest eqtest, Expr c |
60+
eqtest = guard and
61+
eqtest.hasOperands(e, c) and
62+
bounded(c, any(ZeroBound zb), k, upper, _) and
63+
branch = eqtest.polarity()
64+
)
65+
or
66+
exists(Expr c, int val, boolean strict, int d |
67+
bounded(c, any(ZeroBound zb), val, upper, _) and
68+
(
69+
upper = true and
70+
comparison(guard, branch, e, c, strict) and
71+
d = -1
72+
or
73+
upper = false and
74+
comparison(guard, branch, c, e, strict) and
75+
d = 1
76+
) and
77+
(
78+
strict = false and k = val
79+
or
80+
// e < c <= val ==> e <= c - 1 <= val - 1
81+
// e > c >= val ==> e >= c + 1 >= val + 1
82+
strict = true and k = val + d
83+
)
84+
)
85+
}
86+
3587
/**
3688
* An expression that directly tests whether a given expression is equal to `k` or not.
3789
* The set of `k`s is restricted to those that are relevant for the expression or
@@ -53,75 +105,14 @@ Expr integerGuard(IntComparableExpr e, boolean branch, int k, boolean is_k) {
53105
)
54106
)
55107
or
56-
exists(EqualityTest eqtest, int val, Expr c, boolean upper |
57-
k = e.relevantInt() and
58-
eqtest = result and
59-
eqtest.hasOperands(e, c) and
60-
bounded(c, any(ZeroBound zb), val, upper, _) and
61-
is_k = false and
62-
(
63-
upper = true and val < k
64-
or
65-
upper = false and val > k
66-
) and
67-
branch = eqtest.polarity()
68-
)
69-
or
70-
exists(ComparisonExpr comp, Expr c, int val, boolean upper |
108+
exists(int val, boolean upper |
109+
rangeGuard(result, branch, e, val, upper) and
71110
k = e.relevantInt() and
72-
comp = result and
73-
comp.hasOperands(e, c) and
74-
bounded(c, any(ZeroBound zb), val, upper, _) and
75111
is_k = false
76112
|
77-
// k <= val <= c < e, so e != k
78-
comp.getLesserOperand() = c and
79-
comp.isStrict() and
80-
branch = true and
81-
val >= k and
82-
upper = false
83-
or
84-
comp.getLesserOperand() = c and
85-
comp.isStrict() and
86-
branch = false and
87-
val < k and
88-
upper = true
89-
or
90-
comp.getLesserOperand() = c and
91-
not comp.isStrict() and
92-
branch = true and
93-
val > k and
94-
upper = false
113+
upper = true and val < k // e <= val < k ==> e != k
95114
or
96-
comp.getLesserOperand() = c and
97-
not comp.isStrict() and
98-
branch = false and
99-
val <= k and
100-
upper = true
101-
or
102-
comp.getGreaterOperand() = c and
103-
comp.isStrict() and
104-
branch = true and
105-
val <= k and
106-
upper = true
107-
or
108-
comp.getGreaterOperand() = c and
109-
comp.isStrict() and
110-
branch = false and
111-
val > k and
112-
upper = false
113-
or
114-
comp.getGreaterOperand() = c and
115-
not comp.isStrict() and
116-
branch = true and
117-
val < k and
118-
upper = true
119-
or
120-
comp.getGreaterOperand() = c and
121-
not comp.isStrict() and
122-
branch = false and
123-
val >= k and
124-
upper = false
115+
upper = false and val > k // e >= val > k ==> e != k
125116
)
126117
}
127118

0 commit comments

Comments
 (0)