mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
Merge pull request #3445 from geoffw0/rangerounding
C++: Round result of >> in SimpleRangeAnalysis
This commit is contained in:
@@ -140,6 +140,22 @@ private class UnsignedBitwiseAndExpr extends BitwiseAndExpr {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the floor of `v`, with additional logic to work around issues with
|
||||
* large numbers.
|
||||
*/
|
||||
bindingset[v]
|
||||
float safeFloor(float v) {
|
||||
// return the floor of v
|
||||
v.abs() < 2.pow(31) and
|
||||
result = v.floor()
|
||||
or
|
||||
// `floor()` doesn't work correctly on large numbers (since it returns an integer),
|
||||
// so fall back to unrounded numbers at this scale.
|
||||
not v.abs() < 2.pow(31) and
|
||||
result = v
|
||||
}
|
||||
|
||||
/** Set of expressions which we know how to analyze. */
|
||||
private predicate analyzableExpr(Expr e) {
|
||||
// The type of the expression must be arithmetic. We reuse the logic in
|
||||
@@ -709,7 +725,7 @@ private float getLowerBoundsImpl(Expr expr) {
|
||||
rsExpr = expr and
|
||||
left = getFullyConvertedLowerBounds(rsExpr.getLeftOperand()) and
|
||||
right = rsExpr.getRightOperand().getValue().toInt() and
|
||||
result = left / 2.pow(right)
|
||||
result = safeFloor(left / 2.pow(right))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -878,7 +894,7 @@ private float getUpperBoundsImpl(Expr expr) {
|
||||
rsExpr = expr and
|
||||
left = getFullyConvertedUpperBounds(rsExpr.getLeftOperand()) and
|
||||
right = rsExpr.getRightOperand().getValue().toInt() and
|
||||
result = left / 2.pow(right)
|
||||
result = safeFloor(left / 2.pow(right))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -363,4 +363,22 @@ int callCommand(void)
|
||||
if (tmp == 1) // tmp could have been modified by the call.
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int shifts(void)
|
||||
{
|
||||
unsigned int x = 3;
|
||||
|
||||
if (x >> 1 >= 1) {} // always true
|
||||
if (x >> 1 >= 2) {} // always false
|
||||
if (x >> 1 == 1) {} // always true [NOT DETECTED]
|
||||
}
|
||||
|
||||
int bitwise_ands()
|
||||
{
|
||||
unsigned int x = 0xFF;
|
||||
|
||||
if ((x & 2) >= 1) {}
|
||||
if ((x & 2) >= 2) {}
|
||||
if ((x & 2) >= 3) {} // always false
|
||||
}
|
||||
|
||||
@@ -26,4 +26,20 @@ void test1() {
|
||||
if(a.int_member <= 10) {}
|
||||
|
||||
if(volatile_const_global <= 10) {}
|
||||
}
|
||||
}
|
||||
|
||||
int extreme_values(void)
|
||||
{
|
||||
unsigned long long int x = 0xFFFFFFFFFFFFFFFF;
|
||||
unsigned long long int y = 0xFFFFFFFFFFFF;
|
||||
|
||||
if (x >> 1 >= 0xFFFFFFFFFFFFFFFF) {} // always false
|
||||
if (x >> 1 >= 0x8000000000000000) {} // always false [NOT DETECTED]
|
||||
if (x >> 1 >= 0x7FFFFFFFFFFFFFFF) {} // always true [NOT DETECTED]
|
||||
if (x >> 1 >= 0xFFFFFFFFFFFFFFF) {} // always true [NOT DETECTED]
|
||||
|
||||
if (y >> 1 >= 0xFFFFFFFFFFFF) {} // always false [INCORRECT MESSAGE]
|
||||
if (y >> 1 >= 0x800000000000) {} // always false [INCORRECT MESSAGE]
|
||||
if (y >> 1 >= 0x7FFFFFFFFFFF) {} // always true [INCORRECT MESSAGE]
|
||||
if (y >> 1 >= 0xFFFFFFFFFFF) {} // always true [INCORRECT MESSAGE]
|
||||
}
|
||||
|
||||
@@ -38,5 +38,13 @@
|
||||
| PointlessComparison.c:303:9:303:14 | ... >= ... | Comparison is always false because c <= 0. |
|
||||
| PointlessComparison.c:312:9:312:14 | ... >= ... | Comparison is always false because c <= 0. |
|
||||
| PointlessComparison.c:337:14:337:21 | ... >= ... | Comparison is always true because x >= 0. |
|
||||
| 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.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. |
|
||||
| PointlessComparison.cpp:43:6:43:29 | ... >= ... | Comparison is always true because ... >> ... >= 140737488355327.5. |
|
||||
| PointlessComparison.cpp:44:6:44:28 | ... >= ... | Comparison is always true because ... >> ... >= 140737488355327.5. |
|
||||
| RegressionTests.cpp:57:7:57:22 | ... <= ... | Comparison is always true because * ... <= 4294967295. |
|
||||
| Templates.cpp:9:10:9:24 | ... <= ... | Comparison is always true because local <= 32767. |
|
||||
|
||||
Reference in New Issue
Block a user