File tree Expand file tree Collapse file tree 4 files changed +62
-4
lines changed
src/semmle/code/cpp/rangeanalysis
test/query-tests/Likely Bugs/Arithmetic/PointlessComparison Expand file tree Collapse file tree 4 files changed +62
-4
lines changed Original file line number Diff line number Diff line change @@ -140,6 +140,22 @@ private class UnsignedBitwiseAndExpr extends BitwiseAndExpr {
140
140
}
141
141
}
142
142
143
+ /**
144
+ * Gets the floor of `v`, with additional logic to work around issues with
145
+ * large numbers.
146
+ */
147
+ bindingset [ v]
148
+ float safeFloor ( float v ) {
149
+ // return the floor of v
150
+ v .abs ( ) < 2 .pow ( 31 ) and
151
+ result = v .floor ( )
152
+ or
153
+ // `floor()` doesn't work correctly on large numbers (since it returns an integer),
154
+ // so fall back to unrounded numbers at this scale.
155
+ not v .abs ( ) < 2 .pow ( 31 ) and
156
+ result = v
157
+ }
158
+
143
159
/** Set of expressions which we know how to analyze. */
144
160
private predicate analyzableExpr ( Expr e ) {
145
161
// The type of the expression must be arithmetic. We reuse the logic in
@@ -709,7 +725,7 @@ private float getLowerBoundsImpl(Expr expr) {
709
725
rsExpr = expr and
710
726
left = getFullyConvertedLowerBounds ( rsExpr .getLeftOperand ( ) ) and
711
727
right = rsExpr .getRightOperand ( ) .getValue ( ) .toInt ( ) and
712
- result = left / 2 .pow ( right )
728
+ result = safeFloor ( left / 2 .pow ( right ) )
713
729
)
714
730
}
715
731
@@ -878,7 +894,7 @@ private float getUpperBoundsImpl(Expr expr) {
878
894
rsExpr = expr and
879
895
left = getFullyConvertedUpperBounds ( rsExpr .getLeftOperand ( ) ) and
880
896
right = rsExpr .getRightOperand ( ) .getValue ( ) .toInt ( ) and
881
- result = left / 2 .pow ( right )
897
+ result = safeFloor ( left / 2 .pow ( right ) )
882
898
)
883
899
}
884
900
Original file line number Diff line number Diff line change @@ -363,4 +363,22 @@ int callCommand(void)
363
363
if (tmp == 1 ) // tmp could have been modified by the call.
364
364
return 1 ;
365
365
return 0 ;
366
- }
366
+ }
367
+
368
+ int shifts (void )
369
+ {
370
+ unsigned int x = 3 ;
371
+
372
+ if (x >> 1 >= 1 ) {} // always true
373
+ if (x >> 1 >= 2 ) {} // always false
374
+ if (x >> 1 == 1 ) {} // always true [NOT DETECTED]
375
+ }
376
+
377
+ int bitwise_ands ()
378
+ {
379
+ unsigned int x = 0xFF ;
380
+
381
+ if ((x & 2 ) >= 1 ) {}
382
+ if ((x & 2 ) >= 2 ) {}
383
+ if ((x & 2 ) >= 3 ) {} // always false
384
+ }
Original file line number Diff line number Diff line change @@ -26,4 +26,20 @@ void test1() {
26
26
if (a.int_member <= 10 ) {}
27
27
28
28
if (volatile_const_global <= 10 ) {}
29
- }
29
+ }
30
+
31
+ int extreme_values (void )
32
+ {
33
+ unsigned long long int x = 0xFFFFFFFFFFFFFFFF ;
34
+ unsigned long long int y = 0xFFFFFFFFFFFF ;
35
+
36
+ if (x >> 1 >= 0xFFFFFFFFFFFFFFFF ) {} // always false
37
+ if (x >> 1 >= 0x8000000000000000 ) {} // always false [NOT DETECTED]
38
+ if (x >> 1 >= 0x7FFFFFFFFFFFFFFF ) {} // always true [NOT DETECTED]
39
+ if (x >> 1 >= 0xFFFFFFFFFFFFFFF ) {} // always true [NOT DETECTED]
40
+
41
+ if (y >> 1 >= 0xFFFFFFFFFFFF ) {} // always false [INCORRECT MESSAGE]
42
+ if (y >> 1 >= 0x800000000000 ) {} // always false [INCORRECT MESSAGE]
43
+ if (y >> 1 >= 0x7FFFFFFFFFFF ) {} // always true [INCORRECT MESSAGE]
44
+ if (y >> 1 >= 0xFFFFFFFFFFF ) {} // always true [INCORRECT MESSAGE]
45
+ }
Original file line number Diff line number Diff line change 38
38
| PointlessComparison.c:303:9:303:14 | ... >= ... | Comparison is always false because c <= 0. |
39
39
| PointlessComparison.c:312:9:312:14 | ... >= ... | Comparison is always false because c <= 0. |
40
40
| PointlessComparison.c:337:14:337:21 | ... >= ... | Comparison is always true because x >= 0. |
41
+ | PointlessComparison.c:372:6:372:16 | ... >= ... | Comparison is always true because ... >> ... >= 1. |
42
+ | PointlessComparison.c:373:6:373:16 | ... >= ... | Comparison is always false because ... >> ... <= 1. |
43
+ | PointlessComparison.c:383:6:383:17 | ... >= ... | Comparison is always false because ... & ... <= 2. |
44
+ | PointlessComparison.cpp:36:6:36:33 | ... >= ... | Comparison is always false because ... >> ... <= 9223372036854776000. |
45
+ | PointlessComparison.cpp:41:6:41:29 | ... >= ... | Comparison is always false because ... >> ... <= 140737488355327.5. |
46
+ | PointlessComparison.cpp:42:6:42:29 | ... >= ... | Comparison is always false because ... >> ... <= 140737488355327.5. |
47
+ | PointlessComparison.cpp:43:6:43:29 | ... >= ... | Comparison is always true because ... >> ... >= 140737488355327.5. |
48
+ | PointlessComparison.cpp:44:6:44:28 | ... >= ... | Comparison is always true because ... >> ... >= 140737488355327.5. |
41
49
| RegressionTests.cpp:57:7:57:22 | ... <= ... | Comparison is always true because * ... <= 4294967295. |
42
50
| Templates.cpp:9:10:9:24 | ... <= ... | Comparison is always true because local <= 32767. |
You can’t perform that action at this time.
0 commit comments