mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
C++: SimpleRangeAnalysis for *= by constant
This commit is contained in:
@@ -217,8 +217,29 @@ private predicate multipliesByNegative(Expr expr, Expr operand, float negative)
|
||||
negative = -1.0
|
||||
}
|
||||
|
||||
private class AssignMulByConstantExpr extends AssignMulExpr {
|
||||
float constant;
|
||||
|
||||
AssignMulByConstantExpr() { constant = this.getRValue().getFullyConverted().getValue().toFloat() }
|
||||
|
||||
float getConstant() { result = constant }
|
||||
}
|
||||
|
||||
private class AssignMulByPositiveConstantExpr extends AssignMulByConstantExpr {
|
||||
AssignMulByPositiveConstantExpr() { constant >= 0.0 }
|
||||
}
|
||||
|
||||
private class AssignMulByNegativeConstantExpr extends AssignMulByConstantExpr {
|
||||
AssignMulByNegativeConstantExpr() { constant < 0.0 }
|
||||
}
|
||||
|
||||
private class UnsignedAssignMulExpr extends AssignMulExpr {
|
||||
UnsignedAssignMulExpr() { this.getType().(IntegralType).isUnsigned() }
|
||||
UnsignedAssignMulExpr() {
|
||||
this.getType().(IntegralType).isUnsigned() and
|
||||
// Avoid overlap. It should be slightly cheaper to analyze
|
||||
// `AssignMulByConstantExpr`.
|
||||
not this instanceof AssignMulByConstantExpr
|
||||
}
|
||||
}
|
||||
|
||||
/** Set of expressions which we know how to analyze. */
|
||||
@@ -253,6 +274,8 @@ private predicate analyzableExpr(Expr e) {
|
||||
or
|
||||
e instanceof UnsignedAssignMulExpr
|
||||
or
|
||||
e instanceof AssignMulByConstantExpr
|
||||
or
|
||||
e instanceof CrementOperation
|
||||
or
|
||||
e instanceof RemExpr
|
||||
@@ -310,6 +333,12 @@ private predicate defDependsOnDef(
|
||||
exprDependsOnDef(assignMul.getAnOperand(), srcDef, srcVar)
|
||||
)
|
||||
or
|
||||
exists(AssignMulByConstantExpr assignMul |
|
||||
def = assignMul and
|
||||
def.getAVariable() = v and
|
||||
exprDependsOnDef(assignMul.getLValue(), srcDef, srcVar)
|
||||
)
|
||||
or
|
||||
exists(CrementOperation crem |
|
||||
def = crem and
|
||||
def.getAVariable() = v and
|
||||
@@ -365,6 +394,10 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria
|
||||
exprDependsOnDef(mulExpr.getAnOperand(), srcDef, srcVar)
|
||||
)
|
||||
or
|
||||
exists(AssignMulByConstantExpr mulExpr | e = mulExpr |
|
||||
exprDependsOnDef(mulExpr.getLValue(), srcDef, srcVar)
|
||||
)
|
||||
or
|
||||
exists(CrementOperation crementExpr | e = crementExpr |
|
||||
exprDependsOnDef(crementExpr.getOperand(), srcDef, srcVar)
|
||||
)
|
||||
@@ -736,6 +769,18 @@ private float getLowerBoundsImpl(Expr expr) {
|
||||
result = xLow * yLow
|
||||
)
|
||||
or
|
||||
exists(AssignMulByPositiveConstantExpr mulExpr, float xLow |
|
||||
expr = mulExpr and
|
||||
xLow = getFullyConvertedLowerBounds(mulExpr.getLValue()) and
|
||||
result = xLow * mulExpr.getConstant()
|
||||
)
|
||||
or
|
||||
exists(AssignMulByNegativeConstantExpr mulExpr, float xHigh |
|
||||
expr = mulExpr and
|
||||
xHigh = getFullyConvertedUpperBounds(mulExpr.getLValue()) and
|
||||
result = xHigh * mulExpr.getConstant()
|
||||
)
|
||||
or
|
||||
exists(PrefixIncrExpr incrExpr, float xLow |
|
||||
expr = incrExpr and
|
||||
xLow = getFullyConvertedLowerBounds(incrExpr.getOperand()) and
|
||||
@@ -910,6 +955,18 @@ private float getUpperBoundsImpl(Expr expr) {
|
||||
result = xHigh * yHigh
|
||||
)
|
||||
or
|
||||
exists(AssignMulByPositiveConstantExpr mulExpr, float xHigh |
|
||||
expr = mulExpr and
|
||||
xHigh = getFullyConvertedUpperBounds(mulExpr.getLValue()) and
|
||||
result = xHigh * mulExpr.getConstant()
|
||||
)
|
||||
or
|
||||
exists(AssignMulByNegativeConstantExpr mulExpr, float xLow |
|
||||
expr = mulExpr and
|
||||
xLow = getFullyConvertedLowerBounds(mulExpr.getLValue()) and
|
||||
result = xLow * mulExpr.getConstant()
|
||||
)
|
||||
or
|
||||
exists(PrefixIncrExpr incrExpr, float xHigh |
|
||||
expr = incrExpr and
|
||||
xHigh = getFullyConvertedUpperBounds(incrExpr.getOperand()) and
|
||||
@@ -1136,6 +1193,20 @@ private float getDefLowerBoundsImpl(RangeSsaDefinition def, StackVariable v) {
|
||||
result = lhsLB * rhsLB
|
||||
)
|
||||
or
|
||||
exists(AssignMulByPositiveConstantExpr assignMul, RangeSsaDefinition nextDef, float lhsLB |
|
||||
def = assignMul and
|
||||
assignMul.getLValue() = nextDef.getAUse(v) and
|
||||
lhsLB = getDefLowerBounds(nextDef, v) and
|
||||
result = lhsLB * assignMul.getConstant()
|
||||
)
|
||||
or
|
||||
exists(AssignMulByNegativeConstantExpr assignMul, RangeSsaDefinition nextDef, float lhsUB |
|
||||
def = assignMul and
|
||||
assignMul.getLValue() = nextDef.getAUse(v) and
|
||||
lhsUB = getDefUpperBounds(nextDef, v) and
|
||||
result = lhsUB * assignMul.getConstant()
|
||||
)
|
||||
or
|
||||
exists(IncrementOperation incr, float newLB |
|
||||
def = incr and
|
||||
incr.getOperand() = v.getAnAccess() and
|
||||
@@ -1186,6 +1257,20 @@ private float getDefUpperBoundsImpl(RangeSsaDefinition def, StackVariable v) {
|
||||
result = lhsUB * rhsUB
|
||||
)
|
||||
or
|
||||
exists(AssignMulByPositiveConstantExpr assignMul, RangeSsaDefinition nextDef, float lhsUB |
|
||||
def = assignMul and
|
||||
assignMul.getLValue() = nextDef.getAUse(v) and
|
||||
lhsUB = getDefUpperBounds(nextDef, v) and
|
||||
result = lhsUB * assignMul.getConstant()
|
||||
)
|
||||
or
|
||||
exists(AssignMulByNegativeConstantExpr assignMul, RangeSsaDefinition nextDef, float lhsLB |
|
||||
def = assignMul and
|
||||
assignMul.getLValue() = nextDef.getAUse(v) and
|
||||
lhsLB = getDefLowerBounds(nextDef, v) and
|
||||
result = lhsLB * assignMul.getConstant()
|
||||
)
|
||||
or
|
||||
exists(IncrementOperation incr, float newUB |
|
||||
def = incr and
|
||||
incr.getOperand() = v.getAnAccess() and
|
||||
|
||||
@@ -519,9 +519,9 @@
|
||||
| test.c:513:9:513:9 | i | -5 |
|
||||
| test.c:514:9:514:9 | i | -30 |
|
||||
| test.c:516:5:516:5 | i | -30 |
|
||||
| test.c:517:9:517:9 | i | -2147483648 |
|
||||
| test.c:519:5:519:5 | i | -2147483648 |
|
||||
| test.c:520:9:520:9 | i | -2147483648 |
|
||||
| test.c:517:9:517:9 | i | -210 |
|
||||
| test.c:519:5:519:5 | i | -210 |
|
||||
| test.c:520:9:520:9 | i | -1155 |
|
||||
| test.c:522:7:522:7 | i | -2147483648 |
|
||||
| test.c:523:5:523:5 | i | -2147483648 |
|
||||
| test.c:523:9:523:9 | i | -1 |
|
||||
@@ -529,6 +529,9 @@
|
||||
| test.c:526:3:526:3 | i | -2147483648 |
|
||||
| test.c:526:7:526:7 | i | -2147483648 |
|
||||
| test.c:527:10:527:10 | i | -2147483648 |
|
||||
| test.c:530:3:530:3 | i | -2147483648 |
|
||||
| test.c:530:10:530:11 | sc | 1 |
|
||||
| test.c:532:7:532:7 | i | -128 |
|
||||
| test.cpp:10:7:10:7 | b | -2147483648 |
|
||||
| test.cpp:11:5:11:5 | x | -2147483648 |
|
||||
| test.cpp:13:10:13:10 | x | -2147483648 |
|
||||
|
||||
@@ -514,15 +514,22 @@ int mul_by_constant(int i, int j) {
|
||||
out(i); // -30 .. 15
|
||||
|
||||
i *= 7;
|
||||
out(i); // -210 .. 105 [BUG: not supported]
|
||||
out(i); // -210 .. 105
|
||||
|
||||
i *= -11;
|
||||
out(i); // -1155 .. 2310 [BUG: not supported]
|
||||
out(i); // -1155 .. 2310
|
||||
}
|
||||
if (i == -1) {
|
||||
i = i * (int)0xffFFffFF; // fully converted literal is -1
|
||||
out(i); // 1 .. 1
|
||||
}
|
||||
i = i * -1;
|
||||
return i; // -2^31 .. 2^31-1
|
||||
out( i); // -2^31 .. 2^31-1
|
||||
|
||||
signed char sc = 1;
|
||||
i = (*&sc *= 2);
|
||||
out(sc); // demonstrate that we couldn't analyze the LHS of the `*=` above...
|
||||
out(i); // -128 .. 127 // ... but we can still bound its result by its type.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -519,9 +519,9 @@
|
||||
| test.c:513:9:513:9 | i | 10 |
|
||||
| test.c:514:9:514:9 | i | 15 |
|
||||
| test.c:516:5:516:5 | i | 15 |
|
||||
| test.c:517:9:517:9 | i | 2147483647 |
|
||||
| test.c:519:5:519:5 | i | 2147483647 |
|
||||
| test.c:520:9:520:9 | i | 2147483647 |
|
||||
| test.c:517:9:517:9 | i | 105 |
|
||||
| test.c:519:5:519:5 | i | 105 |
|
||||
| test.c:520:9:520:9 | i | 2310 |
|
||||
| test.c:522:7:522:7 | i | 2147483647 |
|
||||
| test.c:523:5:523:5 | i | 2147483647 |
|
||||
| test.c:523:9:523:9 | i | -1 |
|
||||
@@ -529,6 +529,9 @@
|
||||
| test.c:526:3:526:3 | i | 2147483647 |
|
||||
| test.c:526:7:526:7 | i | 2147483647 |
|
||||
| test.c:527:10:527:10 | i | 2147483647 |
|
||||
| test.c:530:3:530:3 | i | 2147483647 |
|
||||
| test.c:530:10:530:11 | sc | 1 |
|
||||
| test.c:532:7:532:7 | i | 127 |
|
||||
| test.cpp:10:7:10:7 | b | 2147483647 |
|
||||
| test.cpp:11:5:11:5 | x | 2147483647 |
|
||||
| test.cpp:13:10:13:10 | x | 2147483647 |
|
||||
|
||||
Reference in New Issue
Block a user