Skip to content

Commit 3fafb85

Browse files
committed
java/ql/lib: update shared range analysis library to use BigInts
1 parent b866ad9 commit 3fafb85

File tree

12 files changed

+193
-161
lines changed

12 files changed

+193
-161
lines changed

java/ql/lib/semmle/code/java/Constants.qll

+26-23
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import java
66

77
signature boolean getBoolValSig(Expr e);
88

9-
signature int getIntValSig(Expr e);
9+
signature QlBuiltins::BigInt getBigIntValSig(Expr e);
1010

1111
/**
1212
* Given predicates defining boolean and integer constants, this module
@@ -15,18 +15,18 @@ signature int getIntValSig(Expr e);
1515
*
1616
* The input and output predicates are expected to be mutually recursive.
1717
*/
18-
module CalculateConstants<getBoolValSig/1 getBoolVal, getIntValSig/1 getIntVal> {
18+
module CalculateConstants<getBoolValSig/1 getBoolVal, getBigIntValSig/1 getBigIntVal> {
1919
/** Gets the value of a constant boolean expression. */
2020
boolean calculateBooleanValue(Expr e) {
2121
// No casts relevant to booleans.
2222
// `!` is the only unary operator that evaluates to a boolean.
2323
result = getBoolVal(e.(LogNotExpr).getExpr()).booleanNot()
2424
or
2525
// Handle binary expressions that have integer operands and a boolean result.
26-
exists(BinaryExpr b, int left, int right |
26+
exists(BinaryExpr b, QlBuiltins::BigInt left, QlBuiltins::BigInt right |
2727
b = e and
28-
left = getIntVal(b.getLeftOperand()) and
29-
right = getIntVal(b.getRightOperand())
28+
left = getBigIntVal(b.getLeftOperand()) and
29+
right = getBigIntVal(b.getRightOperand())
3030
|
3131
(
3232
b instanceof LTExpr and
@@ -97,33 +97,35 @@ module CalculateConstants<getBoolValSig/1 getBoolVal, getIntValSig/1 getIntVal>
9797
)
9898
}
9999

100-
/** Gets the value of a constant integer expression. */
101-
int calculateIntValue(Expr e) {
102-
exists(IntegralType t | e.getType() = t | t.getName().toLowerCase() != "long") and
100+
/** Gets the big int value of a constant integer expression. */
101+
QlBuiltins::BigInt calculateBigIntValue(Expr e) {
102+
e.getType() instanceof IntegralType and
103103
(
104-
exists(CastingExpr cast, int val | cast = e and val = getIntVal(cast.getExpr()) |
104+
exists(CastingExpr cast, QlBuiltins::BigInt val |
105+
cast = e and val = getBigIntVal(cast.getExpr())
106+
|
105107
if cast.getType().hasName("byte")
106-
then result = (val + 128).bitAnd(255) - 128
108+
then result = (val + 128.toBigInt()).bitAnd(255.toBigInt()) - 128.toBigInt()
107109
else
108110
if cast.getType().hasName("short")
109-
then result = (val + 32768).bitAnd(65535) - 32768
111+
then result = (val + 32768.toBigInt()).bitAnd(65535.toBigInt()) - 32768.toBigInt()
110112
else
111113
if cast.getType().hasName("char")
112-
then result = val.bitAnd(65535)
114+
then result = val.bitAnd(65535.toBigInt())
113115
else result = val
114116
)
115117
or
116-
result = getIntVal(e.(PlusExpr).getExpr())
118+
result = getBigIntVal(e.(PlusExpr).getExpr())
117119
or
118-
result = -getIntVal(e.(MinusExpr).getExpr())
120+
result = -getBigIntVal(e.(MinusExpr).getExpr())
119121
or
120-
result = getIntVal(e.(BitNotExpr).getExpr()).bitNot()
122+
result = getBigIntVal(e.(BitNotExpr).getExpr()).bitNot()
121123
or
122124
// No `int` value for `LogNotExpr`.
123-
exists(BinaryExpr b, int v1, int v2 |
125+
exists(BinaryExpr b, QlBuiltins::BigInt v1, QlBuiltins::BigInt v2 |
124126
b = e and
125-
v1 = getIntVal(b.getLeftOperand()) and
126-
v2 = getIntVal(b.getRightOperand())
127+
v1 = getBigIntVal(b.getLeftOperand()) and
128+
v2 = getBigIntVal(b.getRightOperand())
127129
|
128130
b instanceof MulExpr and result = v1 * v2
129131
or
@@ -135,11 +137,12 @@ module CalculateConstants<getBoolValSig/1 getBoolVal, getIntValSig/1 getIntVal>
135137
or
136138
b instanceof SubExpr and result = v1 - v2
137139
or
138-
b instanceof LeftShiftExpr and result = v1.bitShiftLeft(v2)
140+
b instanceof LeftShiftExpr and result = v1.bitShiftLeft(v2.toInt())
139141
or
140-
b instanceof RightShiftExpr and result = v1.bitShiftRightSigned(v2)
142+
b instanceof RightShiftExpr and result = v1.bitShiftRightSigned(v2.toInt())
141143
or
142-
b instanceof UnsignedRightShiftExpr and result = v1.bitShiftRight(v2)
144+
b instanceof UnsignedRightShiftExpr and
145+
result = v1.toInt().bitShiftRight(v2.toInt()).toBigInt() // bitShiftRight not implemented on bigints (yet)
143146
or
144147
b instanceof AndBitwiseExpr and result = v1.bitAnd(v2)
145148
or
@@ -154,12 +157,12 @@ module CalculateConstants<getBoolValSig/1 getBoolVal, getIntValSig/1 getIntVal>
154157
exists(ConditionalExpr ce, boolean condition |
155158
ce = e and
156159
condition = getBoolVal(ce.getCondition()) and
157-
result = getIntVal(ce.getBranchExpr(condition))
160+
result = getBigIntVal(ce.getBranchExpr(condition))
158161
)
159162
or
160163
// If a `Variable` is final, its value is its initializer, if it exists.
161164
exists(Variable v | e = v.getAnAccess() and v.isFinal() |
162-
result = getIntVal(v.getInitializer())
165+
result = getBigIntVal(v.getInitializer())
163166
)
164167
)
165168
}

java/ql/lib/semmle/code/java/Expr.qll

+19-8
Original file line numberDiff line numberDiff line change
@@ -249,25 +249,33 @@ class CompileTimeConstantExpr extends Expr {
249249
* - values of type `long`.
250250
*/
251251
cached
252-
int getIntValue() {
253-
exists(IntegralType t | this.getType() = t | t.getName().toLowerCase() != "long") and
252+
int getIntValue() { result = this.getBigIntValue().toInt() }
253+
254+
/**
255+
* Gets the big integer value of this expression, where possible.
256+
*/
257+
cached
258+
QlBuiltins::BigInt getBigIntValue() {
259+
this.getType() instanceof IntegralType and
254260
(
255-
result = this.(IntegerLiteral).getIntValue()
261+
result = this.(IntegerLiteral).getBigIntValue()
256262
or
257-
result = this.(CharacterLiteral).getCodePointValue()
263+
result = this.(CharacterLiteral).getCodePointValue().toBigInt()
258264
)
259265
or
260-
result = CalcCompileTimeConstants::calculateIntValue(this)
266+
result = CalcCompileTimeConstants::calculateBigIntValue(this)
261267
or
262-
result = this.(LiveLiteral).getValue().getIntValue()
268+
result = this.(LiveLiteral).getValue().getBigIntValue()
263269
}
264270
}
265271

266272
private boolean getBoolValue(Expr e) { result = e.(CompileTimeConstantExpr).getBooleanValue() }
267273

268-
private int getIntValue(Expr e) { result = e.(CompileTimeConstantExpr).getIntValue() }
274+
private QlBuiltins::BigInt getBigIntValue(Expr e) {
275+
result = e.(CompileTimeConstantExpr).getBigIntValue()
276+
}
269277

270-
private module CalcCompileTimeConstants = CalculateConstants<getBoolValue/1, getIntValue/1>;
278+
private module CalcCompileTimeConstants = CalculateConstants<getBoolValue/1, getBigIntValue/1>;
271279

272280
/** An expression parent is an element that may have an expression as its child. */
273281
class ExprParent extends @exprparent, Top { }
@@ -590,6 +598,9 @@ class IntegerLiteral extends Literal, @integerliteral {
590598
/** Gets the int representation of this literal. */
591599
int getIntValue() { result = this.getValue().toInt() }
592600

601+
/** Gets the big int representation of this literal. */
602+
QlBuiltins::BigInt getBigIntValue() { result = this.getValue().toBigInt() }
603+
593604
override string getAPrimaryQlClass() { result = "IntegerLiteral" }
594605
}
595606

java/ql/lib/semmle/code/java/controlflow/internal/GuardsLogic.qll

+2-2
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,9 @@ private predicate guardImpliesNotEqual2(
386386
(
387387
guard = directNullGuard(v0, branch, false) and val = TAbsValNull()
388388
or
389-
exists(int k |
389+
exists(QlBuiltins::BigInt k |
390390
guard = integerGuard(v0.getAUse(), branch, k, false) and
391-
val = TAbsValInt(k)
391+
val = TAbsValInt(k.toInt())
392392
)
393393
) and
394394
(v = v0 or equalVarsInBlock(guard.getBasicBlock(), v0, v))

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

+11-5
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ abstract class Bound extends TBound {
2020
abstract string toString();
2121

2222
/** Gets an expression that equals this bound plus `delta`. */
23-
abstract Expr getExpr(int delta);
23+
abstract Expr getExpr(QlBuiltins::BigInt delta);
2424

2525
/** Gets an expression that equals this bound. */
26-
Expr getExpr() { result = this.getExpr(0) }
26+
Expr getExpr() { result = this.getExpr(0.toBigInt()) }
2727

2828
/** Gets the location of this bound. */
2929
abstract Location getLocation();
@@ -36,7 +36,9 @@ abstract class Bound extends TBound {
3636
class ZeroBound extends Bound, TBoundZero {
3737
override string toString() { result = "0" }
3838

39-
override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta }
39+
override Expr getExpr(QlBuiltins::BigInt delta) {
40+
result.(ConstantIntegerExpr).getIntValue() = delta
41+
}
4042

4143
override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) }
4244
}
@@ -50,7 +52,9 @@ class SsaBound extends Bound, TBoundSsa {
5052

5153
override string toString() { result = this.getSsa().toString() }
5254

53-
override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 }
55+
override Expr getExpr(QlBuiltins::BigInt delta) {
56+
result = this.getSsa().getAUse() and delta = 0.toBigInt()
57+
}
5458

5559
override Location getLocation() { result = this.getSsa().getLocation() }
5660
}
@@ -62,7 +66,9 @@ class SsaBound extends Bound, TBoundSsa {
6266
class ExprBound extends Bound, TBoundExpr {
6367
override string toString() { result = this.getExpr().toString() }
6468

65-
override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 }
69+
override Expr getExpr(QlBuiltins::BigInt delta) {
70+
this = TBoundExpr(result) and delta = 0.toBigInt()
71+
}
6672

6773
override Location getLocation() { result = this.getExpr().getLocation() }
6874
}

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

+10-10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ private import RangeUtils
88
private import RangeAnalysis
99

1010
/** Gets an expression that might have the value `i`. */
11-
private Expr exprWithIntValue(int i) {
11+
private Expr exprWithIntValue(QlBuiltins::BigInt i) {
1212
result.(ConstantIntegerExpr).getIntValue() = i or
1313
result.(ChooseExpr).getAResultExpr() = exprWithIntValue(i)
1414
}
@@ -21,14 +21,14 @@ class IntComparableExpr extends Expr {
2121
IntComparableExpr() { this instanceof VarRead or this instanceof MethodCall }
2222

2323
/** Gets an integer that is directly assigned to the expression in case of a variable; or zero. */
24-
int relevantInt() {
24+
QlBuiltins::BigInt relevantInt() {
2525
exists(SsaExplicitUpdate ssa, SsaSourceVariable v |
2626
this = v.getAnAccess() and
2727
ssa.getSourceVariable() = v and
2828
ssa.getDefiningExpr().(VariableAssign).getSource() = exprWithIntValue(result)
2929
)
3030
or
31-
result = 0
31+
result = 0.toBigInt()
3232
}
3333
}
3434

@@ -41,7 +41,7 @@ class IntComparableExpr extends Expr {
4141
* is true, and different from `k` if `is_k` is false.
4242
*/
4343
pragma[nomagic]
44-
Expr integerGuard(IntComparableExpr e, boolean branch, int k, boolean is_k) {
44+
Expr integerGuard(IntComparableExpr e, boolean branch, QlBuiltins::BigInt k, boolean is_k) {
4545
exists(EqualityTest eqtest, boolean polarity |
4646
eqtest = result and
4747
eqtest.hasOperands(e, any(ConstantIntegerExpr c | c.getIntValue() = k)) and
@@ -53,7 +53,7 @@ Expr integerGuard(IntComparableExpr e, boolean branch, int k, boolean is_k) {
5353
)
5454
)
5555
or
56-
exists(EqualityTest eqtest, int val, Expr c, boolean upper |
56+
exists(EqualityTest eqtest, QlBuiltins::BigInt val, Expr c, boolean upper |
5757
k = e.relevantInt() and
5858
eqtest = result and
5959
eqtest.hasOperands(e, c) and
@@ -67,7 +67,7 @@ Expr integerGuard(IntComparableExpr e, boolean branch, int k, boolean is_k) {
6767
branch = eqtest.polarity()
6868
)
6969
or
70-
exists(ComparisonExpr comp, Expr c, int val, boolean upper |
70+
exists(ComparisonExpr comp, Expr c, QlBuiltins::BigInt val, boolean upper |
7171
k = e.relevantInt() and
7272
comp = result and
7373
comp.hasOperands(e, c) and
@@ -132,8 +132,8 @@ Expr integerGuard(IntComparableExpr e, boolean branch, int k, boolean is_k) {
132132
* If `branch_with_lower_bound_k` is true then `result` is equivalent to `k <= x`
133133
* and if it is false then `result` is equivalent to `k > x`.
134134
*/
135-
Expr intBoundGuard(VarRead x, boolean branch_with_lower_bound_k, int k) {
136-
exists(ComparisonExpr comp, ConstantIntegerExpr c, int val |
135+
Expr intBoundGuard(VarRead x, boolean branch_with_lower_bound_k, QlBuiltins::BigInt k) {
136+
exists(ComparisonExpr comp, ConstantIntegerExpr c, QlBuiltins::BigInt val |
137137
comp = result and
138138
comp.hasOperands(x, c) and
139139
c.getIntValue() = val and
@@ -143,7 +143,7 @@ Expr intBoundGuard(VarRead x, boolean branch_with_lower_bound_k, int k) {
143143
comp.getLesserOperand() = c and
144144
comp.isStrict() and
145145
branch_with_lower_bound_k = true and
146-
val + 1 = k
146+
val + 1.toBigInt() = k
147147
or
148148
// c <= x
149149
comp.getLesserOperand() = c and
@@ -161,6 +161,6 @@ Expr intBoundGuard(VarRead x, boolean branch_with_lower_bound_k, int k) {
161161
comp.getGreaterOperand() = c and
162162
not comp.isStrict() and
163163
branch_with_lower_bound_k = false and
164-
val + 1 = k
164+
val + 1.toBigInt() = k
165165
)
166166
}

0 commit comments

Comments
 (0)