@@ -17,6 +17,7 @@ import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
17
17
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
18
18
import semmle.code.cpp.controlflow.Guards
19
19
import semmle.code.cpp.ir.dataflow.DataFlow
20
+ import semmle.code.cpp.valuenumbering.GlobalValueNumbering
20
21
21
22
/**
22
23
* Holds if `sub` is guarded by a condition which ensures that
@@ -33,46 +34,52 @@ predicate isGuarded(SubExpr sub, Expr left, Expr right) {
33
34
)
34
35
}
35
36
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
+
36
46
/**
37
47
* Holds if `n` is known or suspected to be less than or equal to
38
48
* `sub.getLeftOperand()`.
39
49
*/
40
50
predicate 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 )
74
59
)
75
60
)
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
+ )
76
83
}
77
84
78
85
predicate interestingSubExpr ( SubExpr sub , RelationalOperation ro ) {
0 commit comments