Skip to content

Commit c53f801

Browse files
author
Dave Bartolomeo
authored
Merge pull request #2750 from Cornelius-Riemenschneider/cpp-range-analysis-casts
C++: Support implicit casts better in range analysis
2 parents 81b1bd4 + eafd7b6 commit c53f801

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,13 @@ private predicate boundFlowStepSsa(
187187
guard.controls(op2.getUse().getBlock(), testIsTrue) and
188188
reason = TCondReason(guard)
189189
)
190+
or
191+
exists(IRGuardCondition guard, boolean testIsTrue, SafeCastInstruction cast |
192+
valueNumberOfOperand(op2) = valueNumber(cast.getUnary()) and
193+
guard = boundFlowCond(valueNumber(cast), op1, delta, upper, testIsTrue) and
194+
guard.controls(op2.getUse().getBlock(), testIsTrue) and
195+
reason = TCondReason(guard)
196+
)
190197
}
191198

192199
/**
@@ -259,7 +266,7 @@ private predicate safeCast(IntegralType fromtyp, IntegralType totyp) {
259266

260267
private class SafeCastInstruction extends ConvertInstruction {
261268
SafeCastInstruction() {
262-
safeCast(getResultType(), getUnary().getResultType())
269+
safeCast(getUnary().getResultType(), getResultType())
263270
or
264271
getResultType() instanceof PointerType and
265272
getUnary().getResultType() instanceof PointerType

cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,6 @@
5959
| test.cpp:183:10:183:10 | Load: i | test.cpp:175:23:175:23 | InitializeParameter: x | -1 | true | CompareLT: ... < ... | test.cpp:182:9:182:13 | test.cpp:182:9:182:13 |
6060
| test.cpp:185:10:185:10 | Load: i | test.cpp:175:23:175:23 | InitializeParameter: x | 0 | true | CompareLT: ... < ... | test.cpp:176:7:176:11 | test.cpp:176:7:176:11 |
6161
| test.cpp:187:10:187:10 | Store: i | test.cpp:175:23:175:23 | InitializeParameter: x | 0 | false | CompareLT: ... < ... | test.cpp:182:9:182:13 | test.cpp:182:9:182:13 |
62+
| test.cpp:199:10:199:10 | Load: i | test.cpp:197:25:197:25 | InitializeParameter: l | -1 | true | CompareLT: ... < ... | test.cpp:198:7:198:11 | test.cpp:198:7:198:11 |
63+
| test.cpp:202:11:202:11 | Load: i | test.cpp:197:25:197:25 | InitializeParameter: l | -3 | true | CompareLT: ... < ... | test.cpp:201:7:201:15 | test.cpp:201:7:201:15 |
64+
| test.cpp:208:10:208:10 | Load: x | test.cpp:206:24:206:24 | InitializeParameter: y | -3 | true | CompareLT: ... < ... | test.cpp:207:7:207:15 | test.cpp:207:7:207:15 |

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,25 @@ int test15(int i, int x) {
186186
}
187187
return i;
188188
}
189+
190+
// safe integer type conversion
191+
int test16(int i) {
192+
long l;
193+
l = i;
194+
}
195+
196+
// implicit integer casts
197+
void test17(int i, long l) {
198+
if (i < l) {
199+
sink(i);
200+
}
201+
if (i < l - 2) {
202+
sink (i);
203+
}
204+
}
205+
206+
void test18(int x, int y) {
207+
if (x < y - 2) {
208+
sink(x);
209+
}
210+
}

0 commit comments

Comments
 (0)