@@ -17,6 +17,7 @@ import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
1717import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
1818import semmle.code.cpp.controlflow.Guards
1919import semmle.code.cpp.ir.dataflow.DataFlow
20+ import semmle.code.cpp.valuenumbering.GlobalValueNumbering
2021
2122/**
2223 * Holds if `sub` is guarded by a condition which ensures that
@@ -33,46 +34,52 @@ predicate isGuarded(SubExpr sub, Expr left, Expr right) {
3334 )
3435}
3536
37+ /**
38+ * Gets an expression that is less than or equal to `sub.getLeftOperand()`.
39+ * These serve as the base cases for `exprIsSubLeftOrLess`.
40+ */
41+ Expr exprIsLeftOrLessBase ( SubExpr sub ) {
42+ interestingSubExpr ( sub , _) and // Manual magic
43+ result = sub .getLeftOperand ( )
44+ }
45+
3646/**
3747 * Holds if `n` is known or suspected to be less than or equal to
3848 * `sub.getLeftOperand()`.
3949 */
4050predicate exprIsSubLeftOrLess ( SubExpr sub , DataFlow:: Node n ) {
41- interestingSubExpr ( sub , _) and // Manual magic
42- (
43- n .asExpr ( ) = sub .getLeftOperand ( )
44- or
45- exists ( DataFlow:: Node other |
46- // dataflow
47- exprIsSubLeftOrLess ( sub , other ) and
48- (
49- DataFlow:: localFlowStep ( n , other ) or
50- DataFlow:: localFlowStep ( other , n )
51- )
52- )
53- or
54- exists ( DataFlow:: Node other |
55- // guard constraining `sub`
56- exprIsSubLeftOrLess ( sub , other ) and
57- isGuarded ( sub , other .asExpr ( ) , n .asExpr ( ) ) // other >= n
58- )
59- or
60- exists ( DataFlow:: Node other , float p , float q |
61- // linear access of `other`
62- exprIsSubLeftOrLess ( sub , other ) and
63- linearAccess ( n .asExpr ( ) , other .asExpr ( ) , p , q ) and // n = p * other + q
64- p <= 1 and
65- q <= 0
66- )
67- or
68- exists ( DataFlow:: Node other , float p , float q |
69- // linear access of `n`
70- exprIsSubLeftOrLess ( sub , other ) and
71- linearAccess ( other .asExpr ( ) , n .asExpr ( ) , p , q ) and // other = p * n + q
72- p >= 1 and
73- q >= 0
51+ n .asExpr ( ) = exprIsLeftOrLessBase ( sub )
52+ or
53+ exists ( DataFlow:: Node other |
54+ // dataflow
55+ exprIsSubLeftOrLess ( sub , other ) and
56+ (
57+ DataFlow:: localFlowStep ( n , other ) or
58+ DataFlow:: localFlowStep ( other , n )
7459 )
7560 )
61+ or
62+ exists ( DataFlow:: Node other |
63+ // guard constraining `sub`
64+ exprIsSubLeftOrLess ( sub , other ) and
65+ isGuarded ( sub , other .asExpr ( ) , n .asExpr ( ) ) // other >= n
66+ )
67+ or
68+ exists ( DataFlow:: Node other , float p , float q |
69+ // linear access of `other`
70+ exprIsSubLeftOrLess ( sub , other ) and
71+ linearAccess ( n .asExpr ( ) , other .asExpr ( ) , p , q ) and // n = p * other + q
72+ p <= 1 and
73+ q <= 0
74+ )
75+ or
76+ exists ( DataFlow:: Node other , float p , float q |
77+ // linear access of `n`
78+ exprIsSubLeftOrLess ( sub , other ) and
79+ linearAccess ( other .asExpr ( ) , n .asExpr ( ) , p , q ) and // other = p * n + q
80+ p >= 1 and
81+ q >= 0
82+ )
7683}
7784
7885predicate interestingSubExpr ( SubExpr sub , RelationalOperation ro ) {
0 commit comments