mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55: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:
@@ -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