Skip to content

Commit 93f95b1

Browse files
authored
Merge pull request github#4053 from jbj/SimpleRangeAnalysis-mul
C++: SimpleRangeAnalysis: unsigned multiplication
2 parents ecbbcc2 + 5e5a112 commit 93f95b1

File tree

9 files changed

+1179
-1053
lines changed

9 files changed

+1179
-1053
lines changed

change-notes/1.26/analysis-cpp.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
1414
| **Query** | **Expected impact** | **Change** |
1515
|----------------------------|------------------------|------------------------------------------------------------------|
1616
| Inconsistent direction of for loop (`cpp/inconsistent-loop-direction`) | Fewer false positive results | The query now accounts for intentional wrapping of an unsigned loop counter. |
17+
| Comparison result is always the same (`cpp/constant-comparison`) | More correct results | Bounds on expressions involving multiplication can now be determined in more cases. |
1718

1819
## Changes to libraries
1920

21+
* The `SimpleRangeAnalysis` library now supports multiplications of the form
22+
`e1 * e2` when `e1` and `e2` are unsigned.

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ float safeFloor(float v) {
156156
result = v
157157
}
158158

159+
private class UnsignedMulExpr extends MulExpr {
160+
UnsignedMulExpr() { this.getType().(IntegralType).isUnsigned() }
161+
}
162+
159163
/** Set of expressions which we know how to analyze. */
160164
private predicate analyzableExpr(Expr e) {
161165
// The type of the expression must be arithmetic. We reuse the logic in
@@ -178,6 +182,8 @@ private predicate analyzableExpr(Expr e) {
178182
or
179183
e instanceof SubExpr
180184
or
185+
e instanceof UnsignedMulExpr
186+
or
181187
e instanceof AssignExpr
182188
or
183189
e instanceof AssignAddExpr
@@ -278,6 +284,10 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria
278284
or
279285
exists(SubExpr subExpr | e = subExpr | exprDependsOnDef(subExpr.getAnOperand(), srcDef, srcVar))
280286
or
287+
exists(UnsignedMulExpr mulExpr | e = mulExpr |
288+
exprDependsOnDef(mulExpr.getAnOperand(), srcDef, srcVar)
289+
)
290+
or
281291
exists(AssignExpr addExpr | e = addExpr | exprDependsOnDef(addExpr.getRValue(), srcDef, srcVar))
282292
or
283293
exists(AssignAddExpr addExpr | e = addExpr |
@@ -625,6 +635,13 @@ private float getLowerBoundsImpl(Expr expr) {
625635
result = addRoundingDown(xLow, -yHigh)
626636
)
627637
or
638+
exists(UnsignedMulExpr mulExpr, float xLow, float yLow |
639+
expr = mulExpr and
640+
xLow = getFullyConvertedLowerBounds(mulExpr.getLeftOperand()) and
641+
yLow = getFullyConvertedLowerBounds(mulExpr.getRightOperand()) and
642+
result = xLow * yLow
643+
)
644+
or
628645
exists(AssignExpr assign |
629646
expr = assign and
630647
result = getFullyConvertedLowerBounds(assign.getRValue())
@@ -794,6 +811,13 @@ private float getUpperBoundsImpl(Expr expr) {
794811
result = addRoundingUp(xHigh, -yLow)
795812
)
796813
or
814+
exists(UnsignedMulExpr mulExpr, float xHigh, float yHigh |
815+
expr = mulExpr and
816+
xHigh = getFullyConvertedUpperBounds(mulExpr.getLeftOperand()) and
817+
yHigh = getFullyConvertedUpperBounds(mulExpr.getRightOperand()) and
818+
result = xHigh * yHigh
819+
)
820+
or
797821
exists(AssignExpr assign |
798822
expr = assign and
799823
result = getFullyConvertedUpperBounds(assign.getRValue())

0 commit comments

Comments
 (0)