Skip to content

Commit 707f532

Browse files
committed
C++: Fix bad join-order using a poor man's unbind operator.
1 parent fd596eb commit 707f532

1 file changed

Lines changed: 13 additions & 5 deletions

File tree

cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,24 @@ import semmle.code.cpp.valuenumbering.GlobalValueNumbering
1616
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
1717
import semmle.code.cpp.controlflow.Guards
1818

19+
/** Holds if `sub` is guarded by a condition which ensures that `left >= right`. */
20+
pragma[noinline]
21+
predicate isGuarded(SubExpr sub, Expr left, Expr right) {
22+
exists(GuardCondition guard |
23+
guard.controls(sub.getBasicBlock(), true) and
24+
guard.ensuresLt(left, right, 0, sub.getBasicBlock(), false)
25+
)
26+
}
27+
1928
/** Holds if `sub` will never be negative. */
2029
predicate nonNegative(SubExpr sub) {
2130
not exprMightOverflowNegatively(sub.getFullyConverted())
2231
or
2332
// The subtraction is guarded by a check of the form `left >= right`.
24-
exists(GuardCondition guard, Expr left, Expr right |
25-
left = globalValueNumber(sub.getLeftOperand()).getAnExpr() and
26-
right = globalValueNumber(sub.getRightOperand()).getAnExpr() and
27-
guard.controls(sub.getBasicBlock(), true) and
28-
guard.ensuresLt(left, right, 0, sub.getBasicBlock(), false)
33+
exists(GVN left, GVN right |
34+
strictcount([left, globalValueNumber(sub.getLeftOperand())]) = 1 and
35+
strictcount([right, globalValueNumber(sub.getRightOperand())]) = 1 and
36+
isGuarded(sub, left.getAnExpr(), right.getAnExpr())
2937
)
3038
}
3139

0 commit comments

Comments
 (0)