mirror of
https://github.com/github/codeql.git
synced 2026-04-25 08:45:14 +02:00
Merge pull request #15980 from MathiasVP/guards-lt
C++: Support `<` reasoning for `switch` statements in Guards library
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a predicate `GuardCondition.comparesLt/4` to query whether an expression is compared to a constant.
|
||||
* Added a predicate `GuardCondition.ensuresLt/4` to query whether a basic block is guarded by an expression being less than a constant.
|
||||
@@ -125,6 +125,20 @@ class GuardCondition extends Expr {
|
||||
cached
|
||||
predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) { none() }
|
||||
|
||||
/**
|
||||
* Holds if (determined by this guard) `e < k` evaluates to `isLessThan` if
|
||||
* this expression evaluates to `value`.
|
||||
*/
|
||||
cached
|
||||
predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value) { none() }
|
||||
|
||||
/**
|
||||
* Holds if (determined by this guard) `e < k` must be `isLessThan` in `block`.
|
||||
* If `isLessThan = false` then this implies `e >= k`.
|
||||
*/
|
||||
cached
|
||||
predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) { none() }
|
||||
|
||||
/** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */
|
||||
cached
|
||||
predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) {
|
||||
@@ -176,12 +190,27 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value) {
|
||||
exists(BooleanValue partValue, GuardCondition part |
|
||||
this.(BinaryLogicalOperation)
|
||||
.impliesValue(part, partValue.getValue(), value.(BooleanValue).getValue())
|
||||
|
|
||||
part.comparesLt(e, k, isLessThan, partValue)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
|
||||
exists(boolean testIsTrue |
|
||||
this.comparesLt(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) {
|
||||
exists(AbstractValue value |
|
||||
this.comparesLt(e, k, isLessThan, value) and this.valueControls(block, value)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) {
|
||||
exists(boolean partIsTrue, GuardCondition part |
|
||||
this.(BinaryLogicalOperation).impliesValue(part, partIsTrue, testIsTrue)
|
||||
@@ -227,7 +256,6 @@ private class GuardConditionFromIR extends GuardCondition {
|
||||
this.controlsBlock(controlled, v)
|
||||
}
|
||||
|
||||
/** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */
|
||||
override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) {
|
||||
exists(Instruction li, Instruction ri |
|
||||
li.getUnconvertedResultExpression() = left and
|
||||
@@ -236,10 +264,13 @@ private class GuardConditionFromIR extends GuardCondition {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if (determined by this guard) `left < right + k` must be `isLessThan` in `block`.
|
||||
* If `isLessThan = false` then this implies `left >= right + k`.
|
||||
*/
|
||||
override predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value) {
|
||||
exists(Instruction i |
|
||||
i.getUnconvertedResultExpression() = e and
|
||||
ir.comparesLt(i.getAUse(), k, isLessThan, value)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
|
||||
exists(Instruction li, Instruction ri, boolean testIsTrue |
|
||||
li.getUnconvertedResultExpression() = left and
|
||||
@@ -249,7 +280,14 @@ private class GuardConditionFromIR extends GuardCondition {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */
|
||||
override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) {
|
||||
exists(Instruction i, AbstractValue value |
|
||||
i.getUnconvertedResultExpression() = e and
|
||||
ir.comparesLt(i.getAUse(), k, isLessThan, value) and
|
||||
this.valueControls(block, value)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) {
|
||||
exists(Instruction li, Instruction ri |
|
||||
li.getUnconvertedResultExpression() = left and
|
||||
@@ -258,10 +296,6 @@ private class GuardConditionFromIR extends GuardCondition {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if (determined by this guard) `left == right + k` must be `areEqual` in `block`.
|
||||
* If `areEqual = false` then this implies `left != right + k`.
|
||||
*/
|
||||
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
|
||||
exists(Instruction li, Instruction ri, boolean testIsTrue |
|
||||
li.getUnconvertedResultExpression() = left and
|
||||
@@ -456,7 +490,19 @@ class IRGuardCondition extends Instruction {
|
||||
/** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */
|
||||
cached
|
||||
predicate comparesLt(Operand left, Operand right, int k, boolean isLessThan, boolean testIsTrue) {
|
||||
compares_lt(this, left, right, k, isLessThan, testIsTrue)
|
||||
exists(BooleanValue value |
|
||||
compares_lt(this, left, right, k, isLessThan, value) and
|
||||
value.getValue() = testIsTrue
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if (determined by this guard) `op < k` evaluates to `isLessThan` if
|
||||
* this expression evaluates to `value`.
|
||||
*/
|
||||
cached
|
||||
predicate comparesLt(Operand op, int k, boolean isLessThan, AbstractValue value) {
|
||||
compares_lt(this, op, k, isLessThan, value)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -465,8 +511,19 @@ class IRGuardCondition extends Instruction {
|
||||
*/
|
||||
cached
|
||||
predicate ensuresLt(Operand left, Operand right, int k, IRBlock block, boolean isLessThan) {
|
||||
exists(boolean testIsTrue |
|
||||
compares_lt(this, left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue)
|
||||
exists(AbstractValue value |
|
||||
compares_lt(this, left, right, k, isLessThan, value) and this.valueControls(block, value)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if (determined by this guard) `op < k` must be `isLessThan` in `block`.
|
||||
* If `isLessThan = false` then this implies `op >= k`.
|
||||
*/
|
||||
cached
|
||||
predicate ensuresLt(Operand op, int k, IRBlock block, boolean isLessThan) {
|
||||
exists(AbstractValue value |
|
||||
compares_lt(this, op, k, isLessThan, value) and this.valueControls(block, value)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -478,9 +535,21 @@ class IRGuardCondition extends Instruction {
|
||||
predicate ensuresLtEdge(
|
||||
Operand left, Operand right, int k, IRBlock pred, IRBlock succ, boolean isLessThan
|
||||
) {
|
||||
exists(boolean testIsTrue |
|
||||
compares_lt(this, left, right, k, isLessThan, testIsTrue) and
|
||||
this.controlsEdge(pred, succ, testIsTrue)
|
||||
exists(AbstractValue value |
|
||||
compares_lt(this, left, right, k, isLessThan, value) and
|
||||
this.valueControlsEdge(pred, succ, value)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if (determined by this guard) `op < k` must be `isLessThan` on the edge from
|
||||
* `pred` to `succ`. If `isLessThan = false` then this implies `op >= k`.
|
||||
*/
|
||||
cached
|
||||
predicate ensuresLtEdge(Operand left, int k, IRBlock pred, IRBlock succ, boolean isLessThan) {
|
||||
exists(AbstractValue value |
|
||||
compares_lt(this, left, k, isLessThan, value) and
|
||||
this.valueControlsEdge(pred, succ, value)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -746,31 +815,46 @@ private predicate complex_eq(
|
||||
|
||||
/** Holds if `left < right + k` evaluates to `isLt` given that test is `testIsTrue`. */
|
||||
private predicate compares_lt(
|
||||
Instruction test, Operand left, Operand right, int k, boolean isLt, boolean testIsTrue
|
||||
Instruction test, Operand left, Operand right, int k, boolean isLt, AbstractValue value
|
||||
) {
|
||||
/* In the simple case, the test is the comparison, so isLt = testIsTrue */
|
||||
simple_comparison_lt(test, left, right, k) and isLt = true and testIsTrue = true
|
||||
simple_comparison_lt(test, left, right, k) and
|
||||
value.(BooleanValue).getValue() = isLt
|
||||
or
|
||||
simple_comparison_lt(test, left, right, k) and isLt = false and testIsTrue = false
|
||||
or
|
||||
complex_lt(test, left, right, k, isLt, testIsTrue)
|
||||
complex_lt(test, left, right, k, isLt, value)
|
||||
or
|
||||
/* (not (left < right + k)) => (left >= right + k) */
|
||||
exists(boolean isGe | isLt = isGe.booleanNot() |
|
||||
compares_ge(test, left, right, k, isGe, testIsTrue)
|
||||
)
|
||||
exists(boolean isGe | isLt = isGe.booleanNot() | compares_ge(test, left, right, k, isGe, value))
|
||||
or
|
||||
/* (x is true => (left < right + k)) => (!x is false => (left < right + k)) */
|
||||
exists(boolean isFalse | testIsTrue = isFalse.booleanNot() |
|
||||
compares_lt(test.(LogicalNotInstruction).getUnary(), left, right, k, isLt, isFalse)
|
||||
exists(AbstractValue dual | value = dual.getDualValue() |
|
||||
compares_lt(test.(LogicalNotInstruction).getUnary(), left, right, k, isLt, dual)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `op < k` evaluates to `isLt` given that `test` evaluates to `value`. */
|
||||
private predicate compares_lt(Instruction test, Operand op, int k, boolean isLt, AbstractValue value) {
|
||||
simple_comparison_lt(test, op, k, isLt, value)
|
||||
or
|
||||
complex_lt(test, op, k, isLt, value)
|
||||
or
|
||||
/* (x is true => (op < k)) => (!x is false => (op < k)) */
|
||||
exists(AbstractValue dual | value = dual.getDualValue() |
|
||||
compares_lt(test.(LogicalNotInstruction).getUnary(), op, k, isLt, dual)
|
||||
)
|
||||
or
|
||||
exists(int k1, int k2, ConstantInstruction const |
|
||||
compares_lt(test, op, const.getAUse(), k2, isLt, value) and
|
||||
int_value(const) = k1 and
|
||||
k = k1 + k2
|
||||
)
|
||||
}
|
||||
|
||||
/** `(a < b + k) => (b > a - k) => (b >= a + (1-k))` */
|
||||
private predicate compares_ge(
|
||||
Instruction test, Operand left, Operand right, int k, boolean isGe, boolean testIsTrue
|
||||
Instruction test, Operand left, Operand right, int k, boolean isGe, AbstractValue value
|
||||
) {
|
||||
exists(int onemk | k = 1 - onemk | compares_lt(test, right, left, onemk, isGe, testIsTrue))
|
||||
exists(int onemk | k = 1 - onemk | compares_lt(test, right, left, onemk, isGe, value))
|
||||
}
|
||||
|
||||
/** Rearrange various simple comparisons into `left < right + k` form. */
|
||||
@@ -796,55 +880,99 @@ private predicate simple_comparison_lt(CompareInstruction cmp, Operand left, Ope
|
||||
k = 1
|
||||
}
|
||||
|
||||
private predicate complex_lt(
|
||||
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, boolean testIsTrue
|
||||
/** Rearrange various simple comparisons into `op < k` form. */
|
||||
private predicate simple_comparison_lt(
|
||||
Instruction test, Operand op, int k, boolean isLt, AbstractValue value
|
||||
) {
|
||||
sub_lt(cmp, left, right, k, isLt, testIsTrue)
|
||||
exists(SwitchInstruction switch, CaseEdge case |
|
||||
test = switch.getExpression() and
|
||||
op.getDef() = test and
|
||||
case = value.(MatchValue).getCase() and
|
||||
exists(switch.getSuccessor(case)) and
|
||||
case.getMaxValue() > case.getMinValue()
|
||||
|
|
||||
// op <= k => op < k - 1
|
||||
isLt = true and
|
||||
case.getMaxValue().toInt() = k - 1
|
||||
or
|
||||
isLt = false and
|
||||
case.getMinValue().toInt() = k
|
||||
)
|
||||
}
|
||||
|
||||
private predicate complex_lt(
|
||||
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, AbstractValue value
|
||||
) {
|
||||
sub_lt(cmp, left, right, k, isLt, value)
|
||||
or
|
||||
add_lt(cmp, left, right, k, isLt, testIsTrue)
|
||||
add_lt(cmp, left, right, k, isLt, value)
|
||||
}
|
||||
|
||||
private predicate complex_lt(
|
||||
Instruction test, Operand left, int k, boolean isLt, AbstractValue value
|
||||
) {
|
||||
sub_lt(test, left, k, isLt, value)
|
||||
or
|
||||
add_lt(test, left, k, isLt, value)
|
||||
}
|
||||
|
||||
// left - x < right + c => left < right + (c+x)
|
||||
// left < (right - x) + c => left < right + (c-x)
|
||||
private predicate sub_lt(
|
||||
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, boolean testIsTrue
|
||||
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, AbstractValue value
|
||||
) {
|
||||
exists(SubInstruction lhs, int c, int x |
|
||||
compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
|
||||
compares_lt(cmp, lhs.getAUse(), right, c, isLt, value) and
|
||||
left = lhs.getLeftOperand() and
|
||||
x = int_value(lhs.getRight()) and
|
||||
k = c + x
|
||||
)
|
||||
or
|
||||
exists(SubInstruction rhs, int c, int x |
|
||||
compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
|
||||
compares_lt(cmp, left, rhs.getAUse(), c, isLt, value) and
|
||||
right = rhs.getLeftOperand() and
|
||||
x = int_value(rhs.getRight()) and
|
||||
k = c - x
|
||||
)
|
||||
or
|
||||
exists(PointerSubInstruction lhs, int c, int x |
|
||||
compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
|
||||
compares_lt(cmp, lhs.getAUse(), right, c, isLt, value) and
|
||||
left = lhs.getLeftOperand() and
|
||||
x = int_value(lhs.getRight()) and
|
||||
k = c + x
|
||||
)
|
||||
or
|
||||
exists(PointerSubInstruction rhs, int c, int x |
|
||||
compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
|
||||
compares_lt(cmp, left, rhs.getAUse(), c, isLt, value) and
|
||||
right = rhs.getLeftOperand() and
|
||||
x = int_value(rhs.getRight()) and
|
||||
k = c - x
|
||||
)
|
||||
}
|
||||
|
||||
private predicate sub_lt(Instruction test, Operand left, int k, boolean isLt, AbstractValue value) {
|
||||
exists(SubInstruction lhs, int c, int x |
|
||||
compares_lt(test, lhs.getAUse(), c, isLt, value) and
|
||||
left = lhs.getLeftOperand() and
|
||||
x = int_value(lhs.getRight()) and
|
||||
k = c + x
|
||||
)
|
||||
or
|
||||
exists(PointerSubInstruction lhs, int c, int x |
|
||||
compares_lt(test, lhs.getAUse(), c, isLt, value) and
|
||||
left = lhs.getLeftOperand() and
|
||||
x = int_value(lhs.getRight()) and
|
||||
k = c + x
|
||||
)
|
||||
}
|
||||
|
||||
// left + x < right + c => left < right + (c-x)
|
||||
// left < (right + x) + c => left < right + (c+x)
|
||||
private predicate add_lt(
|
||||
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, boolean testIsTrue
|
||||
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, AbstractValue value
|
||||
) {
|
||||
exists(AddInstruction lhs, int c, int x |
|
||||
compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
|
||||
compares_lt(cmp, lhs.getAUse(), right, c, isLt, value) and
|
||||
(
|
||||
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
|
||||
or
|
||||
@@ -854,7 +982,7 @@ private predicate add_lt(
|
||||
)
|
||||
or
|
||||
exists(AddInstruction rhs, int c, int x |
|
||||
compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
|
||||
compares_lt(cmp, left, rhs.getAUse(), c, isLt, value) and
|
||||
(
|
||||
right = rhs.getLeftOperand() and x = int_value(rhs.getRight())
|
||||
or
|
||||
@@ -864,7 +992,7 @@ private predicate add_lt(
|
||||
)
|
||||
or
|
||||
exists(PointerAddInstruction lhs, int c, int x |
|
||||
compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
|
||||
compares_lt(cmp, lhs.getAUse(), right, c, isLt, value) and
|
||||
(
|
||||
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
|
||||
or
|
||||
@@ -874,7 +1002,7 @@ private predicate add_lt(
|
||||
)
|
||||
or
|
||||
exists(PointerAddInstruction rhs, int c, int x |
|
||||
compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
|
||||
compares_lt(cmp, left, rhs.getAUse(), c, isLt, value) and
|
||||
(
|
||||
right = rhs.getLeftOperand() and x = int_value(rhs.getRight())
|
||||
or
|
||||
@@ -884,6 +1012,28 @@ private predicate add_lt(
|
||||
)
|
||||
}
|
||||
|
||||
private predicate add_lt(Instruction test, Operand left, int k, boolean isLt, AbstractValue value) {
|
||||
exists(AddInstruction lhs, int c, int x |
|
||||
compares_lt(test, lhs.getAUse(), c, isLt, value) and
|
||||
(
|
||||
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
|
||||
or
|
||||
left = lhs.getRightOperand() and x = int_value(lhs.getLeft())
|
||||
) and
|
||||
k = c - x
|
||||
)
|
||||
or
|
||||
exists(PointerAddInstruction lhs, int c, int x |
|
||||
compares_lt(test, lhs.getAUse(), c, isLt, value) and
|
||||
(
|
||||
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
|
||||
or
|
||||
left = lhs.getRightOperand() and x = int_value(lhs.getLeft())
|
||||
) and
|
||||
k = c - x
|
||||
)
|
||||
}
|
||||
|
||||
// left - x == right + c => left == right + (c+x)
|
||||
// left == (right - x) + c => left == right + (c-x)
|
||||
private predicate sub_eq(
|
||||
|
||||
@@ -530,19 +530,27 @@ irGuardsCompare
|
||||
| 7 | 0 < x+0 when CompareGT: ... > ... is true |
|
||||
| 7 | 0 >= x+0 when CompareGT: ... > ... is false |
|
||||
| 7 | x < 0+1 when CompareGT: ... > ... is false |
|
||||
| 7 | x < 1 when CompareGT: ... > ... is false |
|
||||
| 7 | x >= 0+1 when CompareGT: ... > ... is true |
|
||||
| 7 | x >= 1 when CompareGT: ... > ... is true |
|
||||
| 17 | 0 < x+1 when CompareLT: ... < ... is false |
|
||||
| 17 | 0 >= x+1 when CompareLT: ... < ... is true |
|
||||
| 17 | 1 < y+0 when CompareGT: ... > ... is true |
|
||||
| 17 | 1 >= y+0 when CompareGT: ... > ... is false |
|
||||
| 17 | x < 0 when CompareLT: ... < ... is true |
|
||||
| 17 | x < 0+0 when CompareLT: ... < ... is true |
|
||||
| 17 | x >= 0 when CompareLT: ... < ... is false |
|
||||
| 17 | x >= 0+0 when CompareLT: ... < ... is false |
|
||||
| 17 | y < 1+1 when CompareGT: ... > ... is false |
|
||||
| 17 | y < 2 when CompareGT: ... > ... is false |
|
||||
| 17 | y >= 1+1 when CompareGT: ... > ... is true |
|
||||
| 17 | y >= 2 when CompareGT: ... > ... is true |
|
||||
| 26 | 0 < x+0 when CompareGT: ... > ... is true |
|
||||
| 26 | 0 >= x+0 when CompareGT: ... > ... is false |
|
||||
| 26 | x < 0+1 when CompareGT: ... > ... is false |
|
||||
| 26 | x < 1 when CompareGT: ... > ... is false |
|
||||
| 26 | x >= 0+1 when CompareGT: ... > ... is true |
|
||||
| 26 | x >= 1 when CompareGT: ... > ... is true |
|
||||
| 31 | - ... != x+0 when CompareEQ: ... == ... is false |
|
||||
| 31 | - ... == x+0 when CompareEQ: ... == ... is true |
|
||||
| 31 | x != -1 when CompareEQ: ... == ... is false |
|
||||
@@ -551,20 +559,28 @@ irGuardsCompare
|
||||
| 31 | x == - ...+0 when CompareEQ: ... == ... is true |
|
||||
| 34 | 10 < j+1 when CompareLT: ... < ... is false |
|
||||
| 34 | 10 >= j+1 when CompareLT: ... < ... is true |
|
||||
| 34 | j < 10 when CompareLT: ... < ... is true |
|
||||
| 34 | j < 10+0 when CompareLT: ... < ... is true |
|
||||
| 34 | j >= 10 when CompareLT: ... < ... is false |
|
||||
| 34 | j >= 10+0 when CompareLT: ... < ... is false |
|
||||
| 42 | 10 < j+1 when CompareLT: ... < ... is false |
|
||||
| 42 | 10 >= j+1 when CompareLT: ... < ... is true |
|
||||
| 42 | j < 10 when CompareLT: ... < ... is true |
|
||||
| 42 | j < 10+0 when CompareLT: ... < ... is true |
|
||||
| 42 | j >= 10 when CompareLT: ... < ... is false |
|
||||
| 42 | j >= 10+0 when CompareLT: ... < ... is false |
|
||||
| 44 | 0 < z+0 when CompareGT: ... > ... is true |
|
||||
| 44 | 0 >= z+0 when CompareGT: ... > ... is false |
|
||||
| 44 | z < 0+1 when CompareGT: ... > ... is false |
|
||||
| 44 | z < 1 when CompareGT: ... > ... is false |
|
||||
| 44 | z >= 0+1 when CompareGT: ... > ... is true |
|
||||
| 44 | z >= 1 when CompareGT: ... > ... is true |
|
||||
| 45 | 0 < y+0 when CompareGT: ... > ... is true |
|
||||
| 45 | 0 >= y+0 when CompareGT: ... > ... is false |
|
||||
| 45 | y < 0+1 when CompareGT: ... > ... is false |
|
||||
| 45 | y < 1 when CompareGT: ... > ... is false |
|
||||
| 45 | y >= 0+1 when CompareGT: ... > ... is true |
|
||||
| 45 | y >= 1 when CompareGT: ... > ... is true |
|
||||
| 58 | 0 != x+0 when CompareEQ: ... == ... is false |
|
||||
| 58 | 0 < y+1 when CompareLT: ... < ... is false |
|
||||
| 58 | 0 == x+0 when CompareEQ: ... == ... is true |
|
||||
@@ -573,7 +589,9 @@ irGuardsCompare
|
||||
| 58 | x != 0+0 when CompareEQ: ... == ... is false |
|
||||
| 58 | x == 0 when CompareEQ: ... == ... is true |
|
||||
| 58 | x == 0+0 when CompareEQ: ... == ... is true |
|
||||
| 58 | y < 0 when CompareLT: ... < ... is true |
|
||||
| 58 | y < 0+0 when CompareLT: ... < ... is true |
|
||||
| 58 | y >= 0 when CompareLT: ... < ... is false |
|
||||
| 58 | y >= 0+0 when CompareLT: ... < ... is false |
|
||||
| 75 | 0 != x+0 when CompareEQ: ... == ... is false |
|
||||
| 75 | 0 == x+0 when CompareEQ: ... == ... is true |
|
||||
@@ -601,7 +619,9 @@ irGuardsCompare
|
||||
| 94 | x == 0+0 when CompareNE: ... != ... is false |
|
||||
| 102 | 10 < j+1 when CompareLT: ... < ... is false |
|
||||
| 102 | 10 >= j+1 when CompareLT: ... < ... is true |
|
||||
| 102 | j < 10 when CompareLT: ... < ... is true |
|
||||
| 102 | j < 10+0 when CompareLT: ... < ... is true |
|
||||
| 102 | j >= 10 when CompareLT: ... < ... is false |
|
||||
| 102 | j >= 10+0 when CompareLT: ... < ... is false |
|
||||
| 109 | 0 != x+0 when CompareEQ: ... == ... is false |
|
||||
| 109 | 0 < y+1 when CompareLT: ... < ... is false |
|
||||
@@ -611,7 +631,9 @@ irGuardsCompare
|
||||
| 109 | x != 0+0 when CompareEQ: ... == ... is false |
|
||||
| 109 | x == 0 when CompareEQ: ... == ... is true |
|
||||
| 109 | x == 0+0 when CompareEQ: ... == ... is true |
|
||||
| 109 | y < 0 when CompareLT: ... < ... is true |
|
||||
| 109 | y < 0+0 when CompareLT: ... < ... is true |
|
||||
| 109 | y >= 0 when CompareLT: ... < ... is false |
|
||||
| 109 | y >= 0+0 when CompareLT: ... < ... is false |
|
||||
| 156 | ... + ... != x+0 when CompareEQ: ... == ... is false |
|
||||
| 156 | ... + ... == x+0 when CompareEQ: ... == ... is true |
|
||||
@@ -906,8 +928,49 @@ irGuardsEnsure
|
||||
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:12:31:13 | Constant: - ... | == | test.cpp:31:7:31:7 | Load: x | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:12:31:13 | Constant: - ... | == | test.cpp:31:7:31:7 | Load: x | 0 | 32 | 32 |
|
||||
irGuardsEnsure_const
|
||||
| test.c:7:9:7:13 | CompareGT: ... > ... | test.c:7:9:7:9 | Load: x | < | 1 | 11 | 11 |
|
||||
| test.c:7:9:7:13 | CompareGT: ... > ... | test.c:7:9:7:9 | Load: x | >= | 1 | 8 | 8 |
|
||||
| test.c:17:8:17:12 | CompareLT: ... < ... | test.c:17:8:17:8 | Load: x | < | 0 | 17 | 17 |
|
||||
| test.c:17:8:17:12 | CompareLT: ... < ... | test.c:17:8:17:8 | Load: x | < | 0 | 18 | 18 |
|
||||
| test.c:17:17:17:21 | CompareGT: ... > ... | test.c:17:17:17:17 | Load: y | >= | 2 | 18 | 18 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 2 | 2 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 31 | 31 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 34 | 34 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 35 | 35 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 39 | 39 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 42 | 42 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 43 | 43 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 45 | 45 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 46 | 46 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 52 | 52 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 56 | 56 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 58 | 58 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 59 | 59 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | 1 | 62 | 62 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | >= | 1 | 27 | 27 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | < | 10 | 35 | 35 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | 10 | 2 | 2 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | 10 | 39 | 39 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | 10 | 42 | 42 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | 10 | 43 | 43 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | 10 | 45 | 45 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | 10 | 46 | 46 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | 10 | 52 | 52 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | 10 | 56 | 56 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | 10 | 58 | 58 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | 10 | 59 | 59 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | 10 | 62 | 62 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | 10 | 43 | 43 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | 10 | 45 | 45 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | 10 | 46 | 46 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | 10 | 52 | 52 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | < | 1 | 52 | 52 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | >= | 1 | 45 | 45 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | >= | 1 | 46 | 46 |
|
||||
| test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:16:45:16 | Load: y | >= | 1 | 46 | 46 |
|
||||
| test.c:58:9:58:14 | CompareEQ: ... == ... | test.c:58:9:58:9 | Load: x | != | 0 | 58 | 58 |
|
||||
| test.c:58:9:58:14 | CompareEQ: ... == ... | test.c:58:9:58:9 | Load: x | != | 0 | 62 | 62 |
|
||||
| test.c:58:19:58:23 | CompareLT: ... < ... | test.c:58:19:58:19 | Load: y | >= | 0 | 62 | 62 |
|
||||
| test.c:75:9:75:14 | CompareEQ: ... == ... | test.c:75:9:75:9 | Load: x | != | 0 | 79 | 79 |
|
||||
| test.c:75:9:75:14 | CompareEQ: ... == ... | test.c:75:9:75:9 | Load: x | == | 0 | 76 | 76 |
|
||||
| test.c:85:8:85:13 | CompareEQ: ... == ... | test.c:85:8:85:8 | Load: x | == | 0 | 85 | 85 |
|
||||
@@ -922,8 +985,15 @@ irGuardsEnsure_const
|
||||
| test.c:94:11:94:16 | CompareNE: ... != ... | test.c:94:11:94:11 | Load: x | == | 0 | 109 | 109 |
|
||||
| test.c:94:11:94:16 | CompareNE: ... != ... | test.c:94:11:94:11 | Load: x | == | 0 | 110 | 110 |
|
||||
| test.c:94:11:94:16 | CompareNE: ... != ... | test.c:94:11:94:11 | Load: x | == | 0 | 113 | 113 |
|
||||
| test.c:102:16:102:21 | CompareLT: ... < ... | test.c:102:16:102:16 | Load: j | < | 10 | 103 | 103 |
|
||||
| test.c:102:16:102:21 | CompareLT: ... < ... | test.c:102:16:102:16 | Load: j | >= | 10 | 70 | 70 |
|
||||
| test.c:102:16:102:21 | CompareLT: ... < ... | test.c:102:16:102:16 | Load: j | >= | 10 | 107 | 107 |
|
||||
| test.c:102:16:102:21 | CompareLT: ... < ... | test.c:102:16:102:16 | Load: j | >= | 10 | 109 | 109 |
|
||||
| test.c:102:16:102:21 | CompareLT: ... < ... | test.c:102:16:102:16 | Load: j | >= | 10 | 110 | 110 |
|
||||
| test.c:102:16:102:21 | CompareLT: ... < ... | test.c:102:16:102:16 | Load: j | >= | 10 | 113 | 113 |
|
||||
| test.c:109:9:109:14 | CompareEQ: ... == ... | test.c:109:9:109:9 | Load: x | != | 0 | 109 | 109 |
|
||||
| test.c:109:9:109:14 | CompareEQ: ... == ... | test.c:109:9:109:9 | Load: x | != | 0 | 113 | 113 |
|
||||
| test.c:109:19:109:23 | CompareLT: ... < ... | test.c:109:19:109:19 | Load: y | >= | 0 | 113 | 113 |
|
||||
| test.c:175:13:175:32 | CompareEQ: ... == ... | test.c:175:13:175:15 | Call: call to foo | != | 0 | 175 | 175 |
|
||||
| test.c:175:13:175:32 | CompareEQ: ... == ... | test.c:175:13:175:15 | Call: call to foo | == | 0 | 175 | 175 |
|
||||
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | != | -1 | 34 | 34 |
|
||||
|
||||
@@ -96,6 +96,10 @@ query predicate irGuardsCompare(int startLine, string msg) {
|
||||
)
|
||||
or
|
||||
exists(AbstractValue value |
|
||||
guard.comparesLt(left, k, true, value) and op = " < "
|
||||
or
|
||||
guard.comparesLt(left, k, false, value) and op = " >= "
|
||||
or
|
||||
guard.comparesEq(left, k, true, value) and op = " == "
|
||||
or
|
||||
guard.comparesEq(left, k, false, value) and op = " != "
|
||||
@@ -138,6 +142,10 @@ query predicate irGuardsEnsure_const(
|
||||
IRGuardCondition guard, Instruction left, string op, int k, int start, int end
|
||||
) {
|
||||
exists(IRBlock block, Operand leftOp |
|
||||
guard.ensuresLt(leftOp, k, block, true) and op = "<"
|
||||
or
|
||||
guard.ensuresLt(leftOp, k, block, false) and op = ">="
|
||||
or
|
||||
guard.ensuresEq(leftOp, k, block, true) and op = "=="
|
||||
or
|
||||
guard.ensuresEq(leftOp, k, block, false) and op = "!="
|
||||
|
||||
@@ -1,23 +1,33 @@
|
||||
| 7 | 0 < x+0 when ... > ... is true |
|
||||
| 7 | 0 >= x+0 when ... > ... is false |
|
||||
| 7 | x < 0+1 when ... > ... is false |
|
||||
| 7 | x < 1 when ... > ... is false |
|
||||
| 7 | x >= 0+1 when ... > ... is true |
|
||||
| 7 | x >= 1 when ... > ... is true |
|
||||
| 17 | 0 < x+1 when ... < ... is false |
|
||||
| 17 | 0 >= x+1 when ... && ... is true |
|
||||
| 17 | 0 >= x+1 when ... < ... is true |
|
||||
| 17 | 1 < y+0 when ... && ... is true |
|
||||
| 17 | 1 < y+0 when ... > ... is true |
|
||||
| 17 | 1 >= y+0 when ... > ... is false |
|
||||
| 17 | x < 0 when ... && ... is true |
|
||||
| 17 | x < 0 when ... < ... is true |
|
||||
| 17 | x < 0+0 when ... && ... is true |
|
||||
| 17 | x < 0+0 when ... < ... is true |
|
||||
| 17 | x >= 0 when ... < ... is false |
|
||||
| 17 | x >= 0+0 when ... < ... is false |
|
||||
| 17 | y < 1+1 when ... > ... is false |
|
||||
| 17 | y < 2 when ... > ... is false |
|
||||
| 17 | y >= 1+1 when ... && ... is true |
|
||||
| 17 | y >= 1+1 when ... > ... is true |
|
||||
| 17 | y >= 2 when ... && ... is true |
|
||||
| 17 | y >= 2 when ... > ... is true |
|
||||
| 26 | 0 < x+0 when ... > ... is true |
|
||||
| 26 | 0 >= x+0 when ... > ... is false |
|
||||
| 26 | x < 0+1 when ... > ... is false |
|
||||
| 26 | x < 1 when ... > ... is false |
|
||||
| 26 | x >= 0+1 when ... > ... is true |
|
||||
| 26 | x >= 1 when ... > ... is true |
|
||||
| 31 | - ... != x+0 when ... == ... is false |
|
||||
| 31 | - ... == x+0 when ... == ... is true |
|
||||
| 31 | x != -1 when ... == ... is false |
|
||||
@@ -26,20 +36,28 @@
|
||||
| 31 | x == - ...+0 when ... == ... is true |
|
||||
| 34 | 10 < j+1 when ... < ... is false |
|
||||
| 34 | 10 >= j+1 when ... < ... is true |
|
||||
| 34 | j < 10 when ... < ... is true |
|
||||
| 34 | j < 10+0 when ... < ... is true |
|
||||
| 34 | j >= 10 when ... < ... is false |
|
||||
| 34 | j >= 10+0 when ... < ... is false |
|
||||
| 42 | 10 < j+1 when ... < ... is false |
|
||||
| 42 | 10 >= j+1 when ... < ... is true |
|
||||
| 42 | j < 10 when ... < ... is true |
|
||||
| 42 | j < 10+0 when ... < ... is true |
|
||||
| 42 | j >= 10 when ... < ... is false |
|
||||
| 42 | j >= 10+0 when ... < ... is false |
|
||||
| 44 | 0 < z+0 when ... > ... is true |
|
||||
| 44 | 0 >= z+0 when ... > ... is false |
|
||||
| 44 | z < 0+1 when ... > ... is false |
|
||||
| 44 | z < 1 when ... > ... is false |
|
||||
| 44 | z >= 0+1 when ... > ... is true |
|
||||
| 44 | z >= 1 when ... > ... is true |
|
||||
| 45 | 0 < y+0 when ... > ... is true |
|
||||
| 45 | 0 >= y+0 when ... > ... is false |
|
||||
| 45 | y < 0+1 when ... > ... is false |
|
||||
| 45 | y < 1 when ... > ... is false |
|
||||
| 45 | y >= 0+1 when ... > ... is true |
|
||||
| 45 | y >= 1 when ... > ... is true |
|
||||
| 58 | 0 != x+0 when ... == ... is false |
|
||||
| 58 | 0 != x+0 when ... \|\| ... is false |
|
||||
| 58 | 0 < y+1 when ... < ... is false |
|
||||
@@ -52,12 +70,19 @@
|
||||
| 58 | x != 0+0 when ... \|\| ... is false |
|
||||
| 58 | x == 0 when ... == ... is true |
|
||||
| 58 | x == 0+0 when ... == ... is true |
|
||||
| 58 | y < 0 when ... < ... is true |
|
||||
| 58 | y < 0+0 when ... < ... is true |
|
||||
| 58 | y >= 0 when ... < ... is false |
|
||||
| 58 | y >= 0 when ... \|\| ... is false |
|
||||
| 58 | y >= 0+0 when ... < ... is false |
|
||||
| 58 | y >= 0+0 when ... \|\| ... is false |
|
||||
| 61 | i == 0 when i is Case[0] |
|
||||
| 61 | i == 1 when i is Case[1] |
|
||||
| 61 | i == 2 when i is Case[2] |
|
||||
| 74 | i < 11 when i is Case[0..10] |
|
||||
| 74 | i < 21 when i is Case[11..20] |
|
||||
| 74 | i >= 0 when i is Case[0..10] |
|
||||
| 74 | i >= 11 when i is Case[11..20] |
|
||||
| 75 | 0 != x+0 when ... == ... is false |
|
||||
| 75 | 0 == x+0 when ... == ... is true |
|
||||
| 75 | x != 0 when ... == ... is false |
|
||||
@@ -90,7 +115,9 @@
|
||||
| 94 | x == 0+0 when ... != ... is false |
|
||||
| 102 | 10 < j+1 when ... < ... is false |
|
||||
| 102 | 10 >= j+1 when ... < ... is true |
|
||||
| 102 | j < 10 when ... < ... is true |
|
||||
| 102 | j < 10+0 when ... < ... is true |
|
||||
| 102 | j >= 10 when ... < ... is false |
|
||||
| 102 | j >= 10+0 when ... < ... is false |
|
||||
| 109 | 0 != x+0 when ... == ... is false |
|
||||
| 109 | 0 != x+0 when ... \|\| ... is false |
|
||||
@@ -104,6 +131,9 @@
|
||||
| 109 | x != 0+0 when ... \|\| ... is false |
|
||||
| 109 | x == 0 when ... == ... is true |
|
||||
| 109 | x == 0+0 when ... == ... is true |
|
||||
| 109 | y < 0 when ... < ... is true |
|
||||
| 109 | y < 0+0 when ... < ... is true |
|
||||
| 109 | y >= 0 when ... < ... is false |
|
||||
| 109 | y >= 0 when ... \|\| ... is false |
|
||||
| 109 | y >= 0+0 when ... < ... is false |
|
||||
| 109 | y >= 0+0 when ... \|\| ... is false |
|
||||
|
||||
@@ -28,6 +28,10 @@ where
|
||||
)
|
||||
or
|
||||
exists(AbstractValue value |
|
||||
guard.comparesLt(left, k, true, value) and op = " < "
|
||||
or
|
||||
guard.comparesLt(left, k, false, value) and op = " >= "
|
||||
or
|
||||
guard.comparesEq(left, k, true, value) and op = " == "
|
||||
or
|
||||
guard.comparesEq(left, k, false, value) and op = " != "
|
||||
|
||||
Reference in New Issue
Block a user