@@ -14,53 +14,56 @@ import cpp
1414import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
1515import semmle.code.cpp.dataflow.DataFlow
1616
17- predicate illDefinedDecrForStmt ( ForStmt forstmt , Variable v , Expr initialCondition , Expr terminalCondition ) {
18- v .getAnAssignedValue ( ) = initialCondition
19- and
20- exists (
21- RelationalOperation rel |
22- rel = forstmt .getCondition ( ) |
23- terminalCondition = rel .getGreaterOperand ( )
24- and v .getAnAccess ( ) = rel .getLesserOperand ( )
25- and
26- DataFlow:: localFlowStep ( DataFlow:: exprNode ( initialCondition ) , DataFlow:: exprNode ( rel .getLesserOperand ( ) ) )
17+ /**
18+ * A `for` statement whose update is a crement operation on a variable.
19+ */
20+ predicate candidateForStmt ( ForStmt forStmt , Variable v , CrementOperation update , RelationalOperation rel ) {
21+ update = forStmt .getUpdate ( ) and
22+ update .getAnOperand ( ) = v .getAnAccess ( ) and
23+ rel = forStmt .getCondition ( )
24+ }
25+
26+ predicate illDefinedDecrForStmt ( ForStmt forstmt , Variable v , Expr initialCondition , Expr terminalCondition ) {
27+ exists ( DecrementOperation dec , RelationalOperation rel |
28+ // decrementing for loop
29+ candidateForStmt ( forstmt , v , dec , rel ) and
30+
31+ // condition is `v < terminalCondition`
32+ terminalCondition = rel .getGreaterOperand ( ) and
33+ v .getAnAccess ( ) = rel .getLesserOperand ( ) and
34+
35+ // `initialCondition` is a value of `v` in the for loop
36+ v .getAnAssignedValue ( ) = initialCondition and
37+ DataFlow:: localFlowStep ( DataFlow:: exprNode ( initialCondition ) , DataFlow:: exprNode ( rel .getLesserOperand ( ) ) ) and
38+
39+ // `initialCondition` < `terminalCondition`
40+ (
41+ ( upperBound ( initialCondition ) < lowerBound ( terminalCondition ) )
42+ or
43+ ( forstmt .conditionAlwaysFalse ( ) or forstmt .conditionAlwaysTrue ( ) )
2744 )
28- and
29- exists (
30- DecrementOperation dec |
31- dec = forstmt .getUpdate ( ) .( DecrementOperation )
32- and dec .getAnOperand ( ) = v .getAnAccess ( )
33- )
34- and
35- (
36- ( upperBound ( initialCondition ) < lowerBound ( terminalCondition ) )
37- or
38- ( forstmt .conditionAlwaysFalse ( ) or forstmt .conditionAlwaysTrue ( ) )
3945 )
4046}
4147
42- predicate illDefinedIncrForStmt ( ForStmt forstmt , Variable v , Expr initialCondition , Expr terminalCondition ) {
43- v .getAnAssignedValue ( ) = initialCondition
44- and
45- exists (
46- RelationalOperation rel |
47- rel = forstmt .getCondition ( ) |
48- terminalCondition = rel .getLesserOperand ( )
49- and v .getAnAccess ( ) = rel .getGreaterOperand ( )
50- and
51- DataFlow:: localFlowStep ( DataFlow:: exprNode ( initialCondition ) , DataFlow:: exprNode ( rel .getGreaterOperand ( ) ) )
52- )
53- and
54- exists ( IncrementOperation incr |
55- incr = forstmt .getUpdate ( ) .( IncrementOperation )
56- and
57- incr .getAnOperand ( ) = v .getAnAccess ( )
58- )
59- and
60- (
61- ( upperBound ( terminalCondition ) < lowerBound ( initialCondition ) )
62- or
63- ( forstmt .conditionAlwaysFalse ( ) or forstmt .conditionAlwaysTrue ( ) )
48+ predicate illDefinedIncrForStmt ( ForStmt forstmt , Variable v , Expr initialCondition , Expr terminalCondition ) {
49+ exists ( IncrementOperation inc , RelationalOperation rel |
50+ // incrementing for loop
51+ candidateForStmt ( forstmt , v , inc , rel ) and
52+
53+ // condition is `v > terminalCondition`
54+ terminalCondition = rel .getLesserOperand ( ) and
55+ v .getAnAccess ( ) = rel .getGreaterOperand ( ) and
56+
57+ // `initialCondition` is a value of `v` in the for loop
58+ v .getAnAssignedValue ( ) = initialCondition and
59+ DataFlow:: localFlowStep ( DataFlow:: exprNode ( initialCondition ) , DataFlow:: exprNode ( rel .getGreaterOperand ( ) ) ) and
60+
61+ // `terminalCondition` < `initialCondition`
62+ (
63+ ( upperBound ( terminalCondition ) < lowerBound ( initialCondition ) )
64+ or
65+ ( forstmt .conditionAlwaysFalse ( ) or forstmt .conditionAlwaysTrue ( ) )
66+ )
6467 )
6568}
6669
0 commit comments