Skip to content

Commit 71bf61a

Browse files
committed
SimpleRangeAnalysis lib/: float -> BigInt
1 parent 626b1ce commit 71bf61a

File tree

11 files changed

+432
-367
lines changed

11 files changed

+432
-367
lines changed

cpp/ql/lib/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ abstract class SimpleRangeAnalysisDefinition extends RangeSsaDefinition {
5050
* `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
5151
* recursive calls to get the bounds of their dependencies.
5252
*/
53-
abstract float getLowerBounds(StackVariable v);
53+
abstract QlBuiltins::BigInt getLowerBounds(StackVariable v);
5454

5555
/**
5656
* Gets the upper bound of the variable `v` defined by this definition.
@@ -59,7 +59,7 @@ abstract class SimpleRangeAnalysisDefinition extends RangeSsaDefinition {
5959
* `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
6060
* recursive calls to get the bounds of their dependencies.
6161
*/
62-
abstract float getUpperBounds(StackVariable v);
62+
abstract QlBuiltins::BigInt getUpperBounds(StackVariable v);
6363
}
6464

6565
import SimpleRangeAnalysisInternal

cpp/ql/lib/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisExpr.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ abstract class SimpleRangeAnalysisExpr extends Expr {
2121
* `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
2222
* recursive calls to get the bounds of their children.
2323
*/
24-
abstract float getLowerBounds();
24+
abstract QlBuiltins::BigInt getLowerBounds();
2525

2626
/**
2727
* Gets the upper bound of the expression.
@@ -30,7 +30,7 @@ abstract class SimpleRangeAnalysisExpr extends Expr {
3030
* `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
3131
* recursive calls to get the bounds of their children.
3232
*/
33-
abstract float getUpperBounds();
33+
abstract QlBuiltins::BigInt getUpperBounds();
3434

3535
/**
3636
* Holds if the range this expression depends on the definition `srcDef` for
@@ -70,9 +70,9 @@ private class Empty extends SimpleRangeAnalysisExpr {
7070
this = this and none()
7171
}
7272

73-
override float getLowerBounds() { none() }
73+
override QlBuiltins::BigInt getLowerBounds() { none() }
7474

75-
override float getUpperBounds() { none() }
75+
override QlBuiltins::BigInt getUpperBounds() { none() }
7676

7777
override predicate dependsOnChild(Expr child) { none() }
7878
}

cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/ConstantBitwiseAndExprRange.qll

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,34 +46,37 @@ private class ConstantBitwiseAndExprRange extends SimpleRangeAnalysisExpr {
4646
result = this.(AssignAndExpr).getRValue()
4747
}
4848

49-
override float getLowerBounds() {
49+
override QlBuiltins::BigInt getLowerBounds() {
5050
// If an operand can have negative values, the lower bound is unconstrained.
5151
// Otherwise, the lower bound is zero.
52-
exists(float lLower, float rLower |
52+
exists(QlBuiltins::BigInt lLower, QlBuiltins::BigInt rLower |
5353
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
5454
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
5555
(
56-
(lLower < 0 or rLower < 0) and
56+
(lLower < 0.toBigInt() or rLower < 0.toBigInt()) and
5757
result = exprMinVal(this)
5858
or
5959
// This technically results in two lowerBounds when an operand range is negative, but
6060
// that's fine since `exprMinVal(x) <= 0`. We can't use an if statement here without
6161
// non-monotonic recursion issues
62-
result = 0
62+
result = 0.toBigInt()
6363
)
6464
)
6565
}
6666

67-
override float getUpperBounds() {
67+
override QlBuiltins::BigInt getUpperBounds() {
6868
// If an operand can have negative values, the upper bound is unconstrained.
6969
// Otherwise, the upper bound is the minimum of the upper bounds of the operands
70-
exists(float lLower, float lUpper, float rLower, float rUpper |
70+
exists(
71+
QlBuiltins::BigInt lLower, QlBuiltins::BigInt lUpper, QlBuiltins::BigInt rLower,
72+
QlBuiltins::BigInt rUpper
73+
|
7174
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
7275
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
7376
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
7477
rUpper = getFullyConvertedUpperBounds(this.getRightOperand()) and
7578
(
76-
(lLower < 0 or rLower < 0) and
79+
(lLower < 0.toBigInt() or rLower < 0.toBigInt()) and
7780
result = exprMaxVal(this)
7881
or
7982
// This technically results in two upperBounds when an operand range is negative, but

cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/ConstantShiftExprRange.qll

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ private import cpp
22
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
33
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
44

5-
float evaluateConstantExpr(Expr e) {
6-
result = e.getValue().toFloat()
5+
QlBuiltins::BigInt evaluateConstantExpr(Expr e) {
6+
result = parseAsBigInt(e.getValue())
77
or
88
// This handles when a constant value is put into a variable
99
// and the variable is used later
1010
exists(SsaDefinition defn, StackVariable sv |
1111
defn.getAUse(sv) = e and
12-
result = defn.getDefiningValue(sv).getValue().toFloat()
12+
result = parseAsBigInt(defn.getDefiningValue(sv).getValue())
1313
)
1414
}
1515

@@ -18,16 +18,18 @@ float evaluateConstantExpr(Expr e) {
1818
// architecture where the shift value is masked with 0b00011111, but we can't
1919
// assume the architecture).
2020
bindingset[val]
21-
private predicate isValidShiftExprShift(float val, Expr l) {
22-
val >= 0 and
21+
private predicate isValidShiftExprShift(QlBuiltins::BigInt val, Expr l) {
22+
val >= 0.toBigInt() and
2323
// We use getFullyConverted because the spec says to use the *promoted* left operand
24-
val < (l.getFullyConverted().getUnderlyingType().getSize() * 8)
24+
val < (l.getFullyConverted().getUnderlyingType().getSize() * 8).toBigInt()
2525
}
2626

2727
bindingset[val, shift, max_val]
28-
private predicate canLShiftOverflow(int val, int shift, int max_val) {
28+
private predicate canLShiftOverflow(
29+
QlBuiltins::BigInt val, QlBuiltins::BigInt shift, QlBuiltins::BigInt max_val
30+
) {
2931
// val << shift = val * 2^shift > max_val => val > max_val/2^shift = max_val >> b
30-
val > max_val.bitShiftRight(shift)
32+
val > max_val.bitShiftRightSigned(shift.toInt())
3133
}
3234

3335
/**
@@ -65,7 +67,7 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
6567
exists(evaluateConstantExpr(l)) and not exists(evaluateConstantExpr(r))
6668
or
6769
// If the right operand is a constant, check if it is a valid shift expression
68-
exists(float constROp |
70+
exists(QlBuiltins::BigInt constROp |
6971
constROp = evaluateConstantExpr(r) and isValidShiftExprShift(constROp, l)
7072
)
7173
)
@@ -82,8 +84,11 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
8284
result = this.(AssignRShiftExpr).getRValue()
8385
}
8486

85-
override float getLowerBounds() {
86-
exists(int lLower, int lUpper, int rLower, int rUpper |
87+
override QlBuiltins::BigInt getLowerBounds() {
88+
exists(
89+
QlBuiltins::BigInt lLower, QlBuiltins::BigInt lUpper, QlBuiltins::BigInt rLower,
90+
QlBuiltins::BigInt rUpper
91+
|
8792
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
8893
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
8994
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
@@ -92,7 +97,7 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
9297
rLower <= rUpper
9398
|
9499
if
95-
lLower < 0
100+
lLower < 0.toBigInt()
96101
or
97102
not (
98103
isValidShiftExprShift(rLower, this.getLeftOperand()) and
@@ -105,12 +110,15 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
105110
result = exprMinVal(this)
106111
else
107112
// We can get the smallest value by shifting the smallest bound by the largest bound
108-
result = lLower.bitShiftRight(rUpper)
113+
result = lLower.bitShiftRightSigned(rUpper.toInt())
109114
)
110115
}
111116

112-
override float getUpperBounds() {
113-
exists(int lLower, int lUpper, int rLower, int rUpper |
117+
override QlBuiltins::BigInt getUpperBounds() {
118+
exists(
119+
QlBuiltins::BigInt lLower, QlBuiltins::BigInt lUpper, QlBuiltins::BigInt rLower,
120+
QlBuiltins::BigInt rUpper
121+
|
114122
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
115123
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
116124
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
@@ -119,7 +127,7 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
119127
rLower <= rUpper
120128
|
121129
if
122-
lLower < 0
130+
lLower < 0.toBigInt()
123131
or
124132
not (
125133
isValidShiftExprShift(rLower, this.getLeftOperand()) and
@@ -132,7 +140,7 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
132140
result = exprMaxVal(this)
133141
else
134142
// We can get the largest value by shifting the largest bound by the smallest bound
135-
result = lUpper.bitShiftRight(rLower)
143+
result = lUpper.bitShiftRightSigned(rLower.toInt())
136144
)
137145
}
138146

@@ -178,7 +186,7 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
178186
exists(evaluateConstantExpr(l)) and not exists(evaluateConstantExpr(r))
179187
or
180188
// If the right operand is a constant, check if it is a valid shift expression
181-
exists(float constROp |
189+
exists(QlBuiltins::BigInt constROp |
182190
constROp = evaluateConstantExpr(r) and isValidShiftExprShift(constROp, l)
183191
)
184192
)
@@ -195,8 +203,11 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
195203
result = this.(AssignLShiftExpr).getRValue()
196204
}
197205

198-
override float getLowerBounds() {
199-
exists(int lLower, int lUpper, int rLower, int rUpper |
206+
override QlBuiltins::BigInt getLowerBounds() {
207+
exists(
208+
QlBuiltins::BigInt lLower, QlBuiltins::BigInt lUpper, QlBuiltins::BigInt rLower,
209+
QlBuiltins::BigInt rUpper
210+
|
200211
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
201212
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
202213
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
@@ -205,7 +216,7 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
205216
rLower <= rUpper
206217
|
207218
if
208-
lLower < 0
219+
lLower < 0.toBigInt()
209220
or
210221
not (
211222
isValidShiftExprShift(rLower, this.getLeftOperand()) and
@@ -222,12 +233,15 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
222233
// If necessary, we may be able to improve this bound in the future
223234
if canLShiftOverflow(lUpper, rUpper, exprMaxVal(this))
224235
then result = exprMinVal(this)
225-
else result = lLower.bitShiftLeft(rLower)
236+
else result = lLower.bitShiftLeft(rLower.toInt())
226237
)
227238
}
228239

229-
override float getUpperBounds() {
230-
exists(int lLower, int lUpper, int rLower, int rUpper |
240+
override QlBuiltins::BigInt getUpperBounds() {
241+
exists(
242+
QlBuiltins::BigInt lLower, QlBuiltins::BigInt lUpper, QlBuiltins::BigInt rLower,
243+
QlBuiltins::BigInt rUpper
244+
|
231245
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
232246
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
233247
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
@@ -236,7 +250,7 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
236250
rLower <= rUpper
237251
|
238252
if
239-
lLower < 0
253+
lLower < 0.toBigInt()
240254
or
241255
not (
242256
isValidShiftExprShift(rLower, this.getLeftOperand()) and
@@ -253,7 +267,7 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
253267
// If necessary, we may be able to improve this bound in the future
254268
if canLShiftOverflow(lUpper, rUpper, exprMaxVal(this))
255269
then result = exprMaxVal(this)
256-
else result = lUpper.bitShiftLeft(rUpper)
270+
else result = lUpper.bitShiftLeft(rUpper.toInt())
257271
)
258272
}
259273

cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/StrlenLiteralRangeExpr.qll

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ class StrlenLiteralRangeExpr extends SimpleRangeAnalysisExpr, FunctionCall {
1010
this.getTarget().hasGlobalOrStdName("strlen") and this.getArgument(0).isConstant()
1111
}
1212

13-
override int getLowerBounds() { result = this.getArgument(0).getValue().length() }
13+
override QlBuiltins::BigInt getLowerBounds() {
14+
result = this.getArgument(0).getValue().length().toBigInt()
15+
}
1416

15-
override int getUpperBounds() { result = this.getArgument(0).getValue().length() }
17+
override QlBuiltins::BigInt getUpperBounds() {
18+
result = this.getArgument(0).getValue().length().toBigInt()
19+
}
1620

1721
override predicate dependsOnChild(Expr e) { none() }
1822
}

cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/SubtractSelf.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ private class SelfSub extends SimpleRangeAnalysisExpr, SubExpr {
77
this.getRightOperand().getExplicitlyConverted().(VariableAccess).getTarget()
88
}
99

10-
override float getLowerBounds() { result = 0 }
10+
override QlBuiltins::BigInt getLowerBounds() { result = 0.toBigInt() }
1111

12-
override float getUpperBounds() { result = 0 }
12+
override QlBuiltins::BigInt getUpperBounds() { result = 0.toBigInt() }
1313

1414
override predicate dependsOnChild(Expr child) { none() }
1515
}

0 commit comments

Comments
 (0)