mirror of
https://github.com/github/codeql.git
synced 2026-04-25 08:45:14 +02:00
C++: Demonstrate range analysis MulExpr bugs
Unless these issues can be reproduced in far less contrived code, I don't think they will cause problems in practice.
This commit is contained in:
@@ -481,6 +481,26 @@
|
||||
| test.c:461:5:461:9 | total | 0 |
|
||||
| test.c:461:14:461:14 | r | 143 |
|
||||
| test.c:464:10:464:14 | total | 0 |
|
||||
| test.c:469:3:469:3 | x | 0 |
|
||||
| test.c:469:7:469:7 | y | 0 |
|
||||
| test.c:470:3:470:4 | xy | 0 |
|
||||
| test.c:470:8:470:8 | x | 1000000003 |
|
||||
| test.c:470:12:470:12 | y | 1000000003 |
|
||||
| test.c:471:10:471:11 | xy | 1000000006000000000 |
|
||||
| test.c:476:3:476:3 | x | 0 |
|
||||
| test.c:477:3:477:3 | y | 0 |
|
||||
| test.c:478:3:478:4 | xy | 0 |
|
||||
| test.c:478:8:478:8 | x | 274177 |
|
||||
| test.c:478:12:478:12 | y | 67280421310721 |
|
||||
| test.c:479:10:479:11 | xy | 18446744073709552000 |
|
||||
| test.c:483:7:483:8 | ui | 0 |
|
||||
| test.c:484:43:484:44 | ui | 10 |
|
||||
| test.c:484:48:484:49 | ui | 10 |
|
||||
| test.c:485:12:485:17 | result | 100 |
|
||||
| test.c:487:7:487:8 | ul | 0 |
|
||||
| test.c:488:28:488:29 | ul | 10 |
|
||||
| test.c:488:33:488:34 | ul | 10 |
|
||||
| test.c:489:12:489:17 | result | 0 |
|
||||
| test.cpp:10:7:10:7 | b | -2147483648 |
|
||||
| test.cpp:11:5:11:5 | x | -2147483648 |
|
||||
| test.cpp:13:10:13:10 | x | -2147483648 |
|
||||
|
||||
@@ -463,3 +463,30 @@ int test_unsigned_mult02(unsigned b) {
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
unsigned long mult_rounding() {
|
||||
unsigned long x, y, xy;
|
||||
x = y = 1000000003UL; // 1e9 + 3
|
||||
xy = x * y;
|
||||
return xy; // BUG: upper bound should be >= 1000000006000000009UL
|
||||
}
|
||||
|
||||
unsigned long mult_overflow() {
|
||||
unsigned long x, y, xy;
|
||||
x = 274177UL;
|
||||
y = 67280421310721UL;
|
||||
xy = x * y;
|
||||
return xy; // BUG: lower bound should be <= 18446744073709551617UL
|
||||
}
|
||||
|
||||
unsigned long mult_lower_bound(unsigned int ui, unsigned long ul) {
|
||||
if (ui >= 10) {
|
||||
unsigned long result = (unsigned long)ui * ui;
|
||||
return result; // BUG: upper bound should be >= 18446744065119617025 (possibly a pretty-printing bug)
|
||||
}
|
||||
if (ul >= 10) {
|
||||
unsigned long result = ul * ul;
|
||||
return result; // lower bound is correctly 0 (overflow is possible)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -481,6 +481,26 @@
|
||||
| test.c:461:5:461:9 | total | 506 |
|
||||
| test.c:461:14:461:14 | r | 253 |
|
||||
| test.c:464:10:464:14 | total | 759 |
|
||||
| test.c:469:3:469:3 | x | 18446744073709552000 |
|
||||
| test.c:469:7:469:7 | y | 18446744073709552000 |
|
||||
| test.c:470:3:470:4 | xy | 18446744073709552000 |
|
||||
| test.c:470:8:470:8 | x | 1000000003 |
|
||||
| test.c:470:12:470:12 | y | 1000000003 |
|
||||
| test.c:471:10:471:11 | xy | 1000000006000000000 |
|
||||
| test.c:476:3:476:3 | x | 18446744073709552000 |
|
||||
| test.c:477:3:477:3 | y | 18446744073709552000 |
|
||||
| test.c:478:3:478:4 | xy | 18446744073709552000 |
|
||||
| test.c:478:8:478:8 | x | 274177 |
|
||||
| test.c:478:12:478:12 | y | 67280421310721 |
|
||||
| test.c:479:10:479:11 | xy | 18446744073709552000 |
|
||||
| test.c:483:7:483:8 | ui | 4294967295 |
|
||||
| test.c:484:43:484:44 | ui | 4294967295 |
|
||||
| test.c:484:48:484:49 | ui | 4294967295 |
|
||||
| test.c:485:12:485:17 | result | 18446744065119617000 |
|
||||
| test.c:487:7:487:8 | ul | 18446744073709552000 |
|
||||
| test.c:488:28:488:29 | ul | 18446744073709552000 |
|
||||
| test.c:488:33:488:34 | ul | 18446744073709552000 |
|
||||
| test.c:489:12:489:17 | result | 18446744073709552000 |
|
||||
| test.cpp:10:7:10:7 | b | 2147483647 |
|
||||
| test.cpp:11:5:11:5 | x | 2147483647 |
|
||||
| test.cpp:13:10:13:10 | x | 2147483647 |
|
||||
|
||||
@@ -391,4 +391,33 @@ void unsigned_mult(unsigned int x, unsigned int y) {
|
||||
if(x * y < 5) {} // always false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mult_rounding() {
|
||||
unsigned long x, y, xy;
|
||||
x = y = 1000000003UL; // 1e9 + 3
|
||||
xy = 1000000006000000009UL; // x * y, precisely
|
||||
// Even though the range analysis wrongly considers x*y to be xy - 9, there
|
||||
// are no PointlessComparison false positives in these tests because alerts
|
||||
// are suppressed when ulp() < 1, which roughly means that the number is
|
||||
// larger than 2^53.
|
||||
if (x * y < xy) {} // always false [NOT DETECTED]
|
||||
if (x * y > xy) {} // always false [NOT DETECTED]
|
||||
}
|
||||
|
||||
void mult_overflow() {
|
||||
unsigned long x, y;
|
||||
// The following two numbers multiply to 2^64 + 1, which is 1 when truncated
|
||||
// to 64-bit unsigned.
|
||||
x = 274177UL;
|
||||
y = 67280421310721UL;
|
||||
if (x * y == 1) {} // always true [BUG: reported as always false]
|
||||
|
||||
// This bug appears to be caused by
|
||||
// `RangeAnalysisUtils::typeUpperBound(unsigned long)` having a result of
|
||||
// 2**64 + 384, making the range analysis think that the multiplication can't
|
||||
// overflow. The correct `typeUpperBound` would be 2**64 - 1, but we can't
|
||||
// represent that with a QL float or int. We could make `typeUpperBound`
|
||||
// exclusive instead of inclusive, but there is no exclusive upper bound for
|
||||
// floats.
|
||||
}
|
||||
|
||||
@@ -41,6 +41,9 @@
|
||||
| PointlessComparison.c:372:6:372:16 | ... >= ... | Comparison is always true because ... >> ... >= 1. |
|
||||
| PointlessComparison.c:373:6:373:16 | ... >= ... | Comparison is always false because ... >> ... <= 1. |
|
||||
| PointlessComparison.c:383:6:383:17 | ... >= ... | Comparison is always false because ... & ... <= 2. |
|
||||
| PointlessComparison.c:388:10:388:21 | ... > ... | Comparison is always false because ... * ... <= 408. |
|
||||
| PointlessComparison.c:391:12:391:20 | ... < ... | Comparison is always false because ... * ... >= 6. |
|
||||
| PointlessComparison.c:414:7:414:16 | ... == ... | Comparison is always false because ... * ... >= 18446744073709552000. |
|
||||
| PointlessComparison.cpp:36:6:36:33 | ... >= ... | Comparison is always false because ... >> ... <= 9223372036854776000. |
|
||||
| PointlessComparison.cpp:41:6:41:29 | ... >= ... | Comparison is always false because ... >> ... <= 140737488355327.5. |
|
||||
| PointlessComparison.cpp:42:6:42:29 | ... >= ... | Comparison is always false because ... >> ... <= 140737488355327.5. |
|
||||
|
||||
Reference in New Issue
Block a user