Skip to content

Commit ba91f3e

Browse files
authored
Merge pull request #401 from geoffw0/loopdir
CPP: Speed up inconsistentLoopDirection.ql.
2 parents 5cd7103 + a38fefe commit ba91f3e

File tree

1 file changed

+46
-43
lines changed

1 file changed

+46
-43
lines changed

cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql

Lines changed: 46 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,53 +14,56 @@ import cpp
1414
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
1515
import 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

Comments
 (0)