Skip to content

Commit 1ffeebc

Browse files
committed
C++: Range analysis: support casts from/to typedef
1 parent 1c71c74 commit 1ffeebc

File tree

3 files changed

+16
-12
lines changed

3 files changed

+16
-12
lines changed

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,12 @@ predicate linearAccessImpl(Expr expr, VariableAccess v, float p, float q) {
205205
expr = unaryPlusExpr)
206206
or
207207
// (larger_type)(p*v+q) == p*v + q
208-
exists (Cast cast
208+
exists (Cast cast, ArithmeticType sourceType, ArithmeticType targetType
209209
| linearAccess(cast.getExpr(), v, p, q) and
210-
typeLowerBound(cast.getType()) <= typeLowerBound(cast.getExpr().getType()) and
211-
typeUpperBound(cast.getType()) >= typeUpperBound(cast.getExpr().getType()) and
210+
sourceType = cast.getExpr().getType().getUnspecifiedType() and
211+
targetType = cast.getType().getUnspecifiedType() and
212+
typeLowerBound(targetType) <= typeLowerBound(sourceType) and
213+
typeUpperBound(targetType) >= typeUpperBound(sourceType) and
212214
expr = cast)
213215
or
214216
// (p*v+q) == p*v + q
@@ -282,14 +284,14 @@ predicate cmpWithLinearBound(
282284
}
283285

284286
/**
285-
* Holds if `lb` and `ub` are the lower and upper bounds of type `t`
286-
* respectively.
287+
* Holds if `lb` and `ub` are the lower and upper bounds of the unspecified
288+
* type `t`.
287289
*
288290
* For example, if `t` is a signed 32-bit type then holds if `lb` is
289291
* `-2^31` and `ub` is `2^31 - 1`.
290292
*/
291293
private
292-
predicate typeBounds(Type t, float lb, float ub) {
294+
predicate typeBounds(ArithmeticType t, float lb, float ub) {
293295
exists (IntegralType integralType, float limit
294296
| integralType = t and limit = 2.pow(8 * integralType.getSize())
295297
| if integralType instanceof BoolType
@@ -303,22 +305,22 @@ predicate typeBounds(Type t, float lb, float ub) {
303305
}
304306

305307
/**
306-
* Gets the lower bound for type `t`.
308+
* Gets the lower bound for the unspecified type `t`.
307309
*
308310
* For example, if `t` is a signed 32-bit type then the result is
309311
* `-2^31`.
310312
*/
311-
float typeLowerBound(Type t) {
313+
float typeLowerBound(ArithmeticType t) {
312314
typeBounds(t, result, _)
313315
}
314316

315317
/**
316-
* Gets the upper bound for type `t`.
318+
* Gets the upper bound for the unspecified type `t`.
317319
*
318320
* For example, if `t` is a signed 32-bit type then the result is
319321
* `2^31 - 1`.
320322
*/
321-
float typeUpperBound(Type t) {
323+
float typeUpperBound(ArithmeticType t) {
322324
typeBounds(t, _, result)
323325
}
324326

cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ typedef unsigned char u8;
270270

271271
int widening_cast1(u8 c) {
272272
if (c == 0) {
273-
if ((int)c > 0) { // BAD [NOT DETECTED]
273+
if ((int)c > 0) { // BAD
274274
return 1;
275275
}
276276
}
@@ -280,7 +280,7 @@ int widening_cast1(u8 c) {
280280
int widening_cast2(u8 c) {
281281
if (c <= 10)
282282
return -1;
283-
else if ((c >= 11) /* BAD [NOT DETECTED] */ && (c <= 47))
283+
else if ((c >= 11) /* BAD */ && (c <= 47))
284284
return 0;
285285
else
286286
return 1;

cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,7 @@
3333
| PointlessComparison.c:197:7:197:11 | ... < ... | Comparison is always false because x >= 0. |
3434
| PointlessComparison.c:210:6:210:10 | ... < ... | Comparison is always false because e >= 0. |
3535
| PointlessComparison.c:264:12:264:22 | ... >= ... | Comparison is always true because dbl >= 0 and -0 >= - .... |
36+
| PointlessComparison.c:273:9:273:18 | ... > ... | Comparison is always false because c <= 0. |
37+
| PointlessComparison.c:283:13:283:19 | ... >= ... | Comparison is always true because c >= 11. |
3638
| RegressionTests.cpp:57:7:57:22 | ... <= ... | Comparison is always true because * ... <= 4294967295. |
3739
| Templates.cpp:9:10:9:24 | ... <= ... | Comparison is always true because local <= 32767. |

0 commit comments

Comments
 (0)