Skip to content

Commit 3d2ae00

Browse files
authored
Merge pull request #1201 from aschackmull/java/intmulttolong-w-range
Java: Use range analysis in IntMultToLong (ODASA-7836).
2 parents f7dda1b + b5681a1 commit 3d2ae00

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

change-notes/1.21/analysis-java.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
| **Query** | **Expected impact** | **Change** |
1111
|----------------------------|------------------------|------------------------------------------------------------------|
1212
| Implicit conversion from array to string (`java/print-array`) | Fewer false positive results | Results in slf4j logging calls are no longer reported as slf4j supports array printing. |
13+
| Result of multiplication cast to wider type (`java/integer-multiplication-cast-to-long`) | Fewer false positive results | Range analysis is now used to exclude results involving multiplication of small values that cannot overflow. |
1314

1415
## Changes to QL libraries
1516

java/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,26 @@
1818

1919
import java
2020
import semmle.code.java.dataflow.RangeUtils
21+
import semmle.code.java.dataflow.RangeAnalysis
2122
import semmle.code.java.Conversions
2223

23-
/** An multiplication that does not overflow. */
24+
/** Gets an upper bound on the absolute value of `e`. */
25+
float exprBound(Expr e) {
26+
result = e.(ConstantIntegerExpr).getIntValue().(float).abs()
27+
or
28+
exists(float lower, float upper |
29+
bounded(e, any(ZeroBound zb), lower, false, _) and
30+
bounded(e, any(ZeroBound zb), upper, true, _) and
31+
result = upper.abs().maximum(lower.abs())
32+
)
33+
}
34+
35+
/** A multiplication that does not overflow. */
2436
predicate small(MulExpr e) {
2537
exists(NumType t, float lhs, float rhs, float res | t = e.getType() |
26-
lhs = e.getLeftOperand().getProperExpr().(ConstantIntegerExpr).getIntValue() and
27-
rhs = e.getRightOperand().getProperExpr().(ConstantIntegerExpr).getIntValue() and
38+
lhs = exprBound(e.getLeftOperand().getProperExpr()) and
39+
rhs = exprBound(e.getRightOperand().getProperExpr()) and
2840
lhs * rhs = res and
29-
t.getOrdPrimitiveType().getMinValue() <= res and
3041
res <= t.getOrdPrimitiveType().getMaxValue()
3142
)
3243
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
public class Test2 {
2+
// IntMultToLong
3+
void foo() {
4+
for (int k = 1; k < 10; k++) {
5+
long res = k * 1000; // OK
6+
}
7+
}
8+
}

0 commit comments

Comments
 (0)