Skip to content

Commit a457d54

Browse files
author
Robert Marsh
authored
Merge pull request #4078 from jbj/SimpleRangeAnalysis-AssignMulExpr
C++: Range analysis for unsigned AssignMulExpr
2 parents b14bc42 + 21d16d1 commit a457d54

File tree

4 files changed

+85
-11
lines changed

4 files changed

+85
-11
lines changed

cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ private class UnsignedMulExpr extends MulExpr {
161161
UnsignedMulExpr() { this.getType().(IntegralType).isUnsigned() }
162162
}
163163

164+
private class UnsignedAssignMulExpr extends AssignMulExpr {
165+
UnsignedAssignMulExpr() { this.getType().(IntegralType).isUnsigned() }
166+
}
167+
164168
/** Set of expressions which we know how to analyze. */
165169
private predicate analyzableExpr(Expr e) {
166170
// The type of the expression must be arithmetic. We reuse the logic in
@@ -191,6 +195,8 @@ private predicate analyzableExpr(Expr e) {
191195
or
192196
e instanceof AssignSubExpr
193197
or
198+
e instanceof UnsignedAssignMulExpr
199+
or
194200
e instanceof CrementOperation
195201
or
196202
e instanceof RemExpr
@@ -237,25 +243,27 @@ private predicate defDependsOnDef(
237243
// Definitions with a defining value.
238244
exists(Expr expr | assignmentDef(def, v, expr) | exprDependsOnDef(expr, srcDef, srcVar))
239245
or
240-
exists(AssignAddExpr assignAdd, RangeSsaDefinition nextDef |
246+
exists(AssignAddExpr assignAdd |
241247
def = assignAdd and
242-
assignAdd.getLValue() = nextDef.getAUse(v)
243-
|
244-
defDependsOnDef(nextDef, v, srcDef, srcVar) or
245-
exprDependsOnDef(assignAdd.getRValue(), srcDef, srcVar)
248+
def.getAVariable() = v and
249+
exprDependsOnDef(assignAdd.getAnOperand(), srcDef, srcVar)
246250
)
247251
or
248-
exists(AssignSubExpr assignSub, RangeSsaDefinition nextDef |
252+
exists(AssignSubExpr assignSub |
249253
def = assignSub and
250-
assignSub.getLValue() = nextDef.getAUse(v)
251-
|
252-
defDependsOnDef(nextDef, v, srcDef, srcVar) or
253-
exprDependsOnDef(assignSub.getRValue(), srcDef, srcVar)
254+
def.getAVariable() = v and
255+
exprDependsOnDef(assignSub.getAnOperand(), srcDef, srcVar)
256+
)
257+
or
258+
exists(UnsignedAssignMulExpr assignMul |
259+
def = assignMul and
260+
def.getAVariable() = v and
261+
exprDependsOnDef(assignMul.getAnOperand(), srcDef, srcVar)
254262
)
255263
or
256264
exists(CrementOperation crem |
257265
def = crem and
258-
crem.getOperand() = v.getAnAccess() and
266+
def.getAVariable() = v and
259267
exprDependsOnDef(crem.getOperand(), srcDef, srcVar)
260268
)
261269
or
@@ -302,6 +310,10 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria
302310
exprDependsOnDef(subExpr.getAnOperand(), srcDef, srcVar)
303311
)
304312
or
313+
exists(UnsignedAssignMulExpr mulExpr | e = mulExpr |
314+
exprDependsOnDef(mulExpr.getAnOperand(), srcDef, srcVar)
315+
)
316+
or
305317
exists(CrementOperation crementExpr | e = crementExpr |
306318
exprDependsOnDef(crementExpr.getOperand(), srcDef, srcVar)
307319
)
@@ -669,6 +681,13 @@ private float getLowerBoundsImpl(Expr expr) {
669681
result = addRoundingDown(xLow, -yHigh)
670682
)
671683
or
684+
exists(UnsignedAssignMulExpr mulExpr, float xLow, float yLow |
685+
expr = mulExpr and
686+
xLow = getFullyConvertedLowerBounds(mulExpr.getLValue()) and
687+
yLow = getFullyConvertedLowerBounds(mulExpr.getRValue()) and
688+
result = xLow * yLow
689+
)
690+
or
672691
exists(PrefixIncrExpr incrExpr, float xLow |
673692
expr = incrExpr and
674693
xLow = getFullyConvertedLowerBounds(incrExpr.getOperand()) and
@@ -853,6 +872,13 @@ private float getUpperBoundsImpl(Expr expr) {
853872
result = addRoundingUp(xHigh, -yLow)
854873
)
855874
or
875+
exists(UnsignedAssignMulExpr mulExpr, float xHigh, float yHigh |
876+
expr = mulExpr and
877+
xHigh = getFullyConvertedUpperBounds(mulExpr.getLValue()) and
878+
yHigh = getFullyConvertedUpperBounds(mulExpr.getRValue()) and
879+
result = xHigh * yHigh
880+
)
881+
or
856882
exists(PrefixIncrExpr incrExpr, float xHigh |
857883
expr = incrExpr and
858884
xHigh = getFullyConvertedUpperBounds(incrExpr.getOperand()) and
@@ -1089,6 +1115,14 @@ private float getDefLowerBoundsImpl(RangeSsaDefinition def, StackVariable v) {
10891115
result = addRoundingDown(lhsLB, -rhsUB)
10901116
)
10911117
or
1118+
exists(UnsignedAssignMulExpr assignMul, RangeSsaDefinition nextDef, float lhsLB, float rhsLB |
1119+
def = assignMul and
1120+
assignMul.getLValue() = nextDef.getAUse(v) and
1121+
lhsLB = getDefLowerBounds(nextDef, v) and
1122+
rhsLB = getFullyConvertedLowerBounds(assignMul.getRValue()) and
1123+
result = lhsLB * rhsLB
1124+
)
1125+
or
10921126
exists(IncrementOperation incr, float newLB |
10931127
def = incr and
10941128
incr.getOperand() = v.getAnAccess() and
@@ -1131,6 +1165,14 @@ private float getDefUpperBoundsImpl(RangeSsaDefinition def, StackVariable v) {
11311165
result = addRoundingUp(lhsUB, -rhsLB)
11321166
)
11331167
or
1168+
exists(UnsignedAssignMulExpr assignMul, RangeSsaDefinition nextDef, float lhsUB, float rhsUB |
1169+
def = assignMul and
1170+
assignMul.getLValue() = nextDef.getAUse(v) and
1171+
lhsUB = getDefUpperBounds(nextDef, v) and
1172+
rhsUB = getFullyConvertedUpperBounds(assignMul.getRValue()) and
1173+
result = lhsUB * rhsUB
1174+
)
1175+
or
11341176
exists(IncrementOperation incr, float newUB |
11351177
def = incr and
11361178
incr.getOperand() = v.getAnAccess() and

cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBound.expected

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,15 @@
501501
| test.c:488:28:488:29 | ul | 10 |
502502
| test.c:488:33:488:34 | ul | 10 |
503503
| test.c:489:12:489:17 | result | 0 |
504+
| test.c:495:7:495:8 | ui | 0 |
505+
| test.c:495:19:495:20 | ui | 0 |
506+
| test.c:496:5:496:6 | ui | 2 |
507+
| test.c:496:11:496:12 | ui | 2 |
508+
| test.c:497:12:497:13 | ui | 4 |
509+
| test.c:501:3:501:9 | uiconst | 10 |
510+
| test.c:504:3:504:9 | ulconst | 10 |
511+
| test.c:505:10:505:16 | uiconst | 40 |
512+
| test.c:505:20:505:26 | ulconst | 40 |
504513
| test.cpp:10:7:10:7 | b | -2147483648 |
505514
| test.cpp:11:5:11:5 | x | -2147483648 |
506515
| test.cpp:13:10:13:10 | x | -2147483648 |

cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/test.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,17 @@ unsigned long mult_lower_bound(unsigned int ui, unsigned long ul) {
490490
}
491491
return 0;
492492
}
493+
494+
unsigned long mul_assign(unsigned int ui) {
495+
if (ui <= 10 && ui >= 2) {
496+
ui *= ui + 0;
497+
return ui; // 4 .. 100
498+
}
499+
500+
unsigned int uiconst = 10;
501+
uiconst *= 4;
502+
503+
unsigned long ulconst = 10;
504+
ulconst *= 4;
505+
return uiconst + ulconst; // 40 .. 40 for both
506+
}

cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/upperBound.expected

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,15 @@
501501
| test.c:488:28:488:29 | ul | 18446744073709551616 |
502502
| test.c:488:33:488:34 | ul | 18446744073709551616 |
503503
| test.c:489:12:489:17 | result | 18446744073709551616 |
504+
| test.c:495:7:495:8 | ui | 4294967295 |
505+
| test.c:495:19:495:20 | ui | 10 |
506+
| test.c:496:5:496:6 | ui | 10 |
507+
| test.c:496:11:496:12 | ui | 10 |
508+
| test.c:497:12:497:13 | ui | 100 |
509+
| test.c:501:3:501:9 | uiconst | 10 |
510+
| test.c:504:3:504:9 | ulconst | 10 |
511+
| test.c:505:10:505:16 | uiconst | 40 |
512+
| test.c:505:20:505:26 | ulconst | 40 |
504513
| test.cpp:10:7:10:7 | b | 2147483647 |
505514
| test.cpp:11:5:11:5 | x | 2147483647 |
506515
| test.cpp:13:10:13:10 | x | 2147483647 |

0 commit comments

Comments
 (0)