@@ -16,16 +16,24 @@ import semmle.code.cpp.valuenumbering.GlobalValueNumbering
1616import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
1717import 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. */
2029predicate 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