Skip to content

Commit 38b5fbc

Browse files
committed
Decouple ForStmt from Increment.qll and rewrite getLoopStepOfForStmt
1 parent 2227255 commit 38b5fbc

File tree

2 files changed

+63
-60
lines changed

2 files changed

+63
-60
lines changed
Lines changed: 61 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,76 @@
1-
import cpp
2-
3-
abstract class LegacyForLoopUpdateExpression extends Expr {
4-
ForStmt forLoop;
5-
6-
LegacyForLoopUpdateExpression() { this = forLoop.getUpdate().getAChild*() }
7-
8-
abstract Expr getLoopStep();
9-
/* TODO: Complete below and use it for 3-2 */
10-
// abstract VariableAccess getUpdatedVariable();
11-
}
1+
/**
2+
* Provides a library for working with expressions that update the value
3+
* of a numeric variable by incrementing or decrementing it by a certain
4+
* amount.
5+
*/
126

13-
class CrementLegacyForLoopUpdateExpression extends LegacyForLoopUpdateExpression {
14-
CrementLegacyForLoopUpdateExpression() { this instanceof CrementOperation }
15-
16-
override Expr getLoopStep() { none() }
17-
}
7+
import cpp
188

19-
class AssignAddOrSubExpr extends LegacyForLoopUpdateExpression {
9+
private class AssignAddOrSubExpr extends AssignArithmeticOperation {
2010
AssignAddOrSubExpr() {
2111
this instanceof AssignAddExpr or
2212
this instanceof AssignSubExpr
2313
}
14+
}
2415

25-
override Expr getLoopStep() {
26-
result = this.(AssignAddExpr).getRValue() or
27-
result = this.(AssignSubExpr).getRValue()
16+
private class AddOrSubExpr extends BinaryArithmeticOperation {
17+
AddOrSubExpr() {
18+
this instanceof AddExpr or
19+
this instanceof SubExpr
2820
}
2921
}
3022

31-
class AddOrSubThenAssignExpr extends LegacyForLoopUpdateExpression {
32-
Expr assignRhs;
23+
/**
24+
* An expression that updates a numeric variable by adding to or subtracting
25+
* from it a certain amount.
26+
*/
27+
abstract class StepCrementUpdateExpr extends Expr {
28+
/**
29+
* The expression in the abstract syntax tree that represents the amount of
30+
* value by which the variable is updated.
31+
*/
32+
abstract Expr getAmountExpr();
33+
}
34+
35+
/**
36+
* An increment or decrement operator application, either postfix or prefix.
37+
*/
38+
class PostfixOrPrefixCrementExpr extends CrementOperation, StepCrementUpdateExpr {
39+
override Expr getAmountExpr() { none() }
40+
}
41+
42+
/**
43+
* An add-then-assign or subtract-then-assign expression in a shortened form,
44+
* i.e. `+=` or `-=`.
45+
*/
46+
class AssignAddOrSubUpdateExpr extends AssignAddOrSubExpr, StepCrementUpdateExpr {
47+
override Expr getAmountExpr() { result = this.getRValue() }
48+
}
49+
50+
/**
51+
* An add-then-assign expression or a subtract-then-assign expression, i.e.
52+
* `x = x + E` or `x = x - E`, where `x` is some variable and `E` an
53+
* arbitrary expression.
54+
*/
55+
class AddOrSubThenAssignExpr extends AssignExpr, StepCrementUpdateExpr {
56+
/** The `x` as in the left-hand side of `x = x + E`. */
57+
VariableAccess lvalueVariable;
58+
/** The `x + E` as in `x = x + E`. */
59+
AddOrSubExpr addOrSubExpr;
60+
/** The `E` as in `x = x + E`. */
61+
Expr amountExpr;
3362

3463
AddOrSubThenAssignExpr() {
35-
this.(AssignExpr).getRValue() = assignRhs and
36-
(
37-
assignRhs instanceof AddExpr or
38-
assignRhs instanceof SubExpr
64+
this.getLValue() = lvalueVariable and
65+
this.getRValue() = addOrSubExpr and
66+
exists(VariableAccess lvalueVariableAsRvalue |
67+
lvalueVariableAsRvalue = addOrSubExpr.getAnOperand() and
68+
amountExpr = addOrSubExpr.getAnOperand() and
69+
lvalueVariableAsRvalue != amountExpr
70+
|
71+
lvalueVariable.getTarget() = lvalueVariableAsRvalue.(VariableAccess).getTarget()
3972
)
4073
}
4174

42-
override Expr getLoopStep() {
43-
(
44-
result = assignRhs.(AddExpr).getAnOperand() or
45-
result = assignRhs.(SubExpr).getAnOperand()
46-
) and
47-
exists(VariableAccess iterationVariableAccess |
48-
(
49-
iterationVariableAccess = assignRhs.(AddExpr).getAnOperand()
50-
or
51-
iterationVariableAccess = assignRhs.(SubExpr).getAnOperand()
52-
) and
53-
iterationVariableAccess.getTarget() = forLoop.getAnIterationVariable() and
54-
result != iterationVariableAccess
55-
)
56-
}
57-
}
75+
override Expr getAmountExpr() { result = amountExpr }
76+
}

cpp/misra/src/rules/RULE-9-5-1/LegacyForStatementsShouldBeSimple.ql

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,7 @@ Expr getLoopStepOfForStmt(ForStmt forLoop) {
6666
*/
6767

6868
/* 1. Get the expression `E` when the update expression is `i += E` or `i -= E`. */
69-
result = forLoop.getUpdate().getAChild*().(AssignAddOrSubExpr).getLoopStep()
70-
or
71-
/* 2. Get the expression `E` when the update expression is `i = i + E` or `i = i - E`. */
72-
(
73-
result = forLoop.getUpdate().getAChild*().(AssignExpr).getRValue().(AddExpr).getAnOperand() or
74-
result = forLoop.getUpdate().getAChild*().(AssignExpr).getRValue().(SubExpr).getAnOperand()
75-
) and
76-
exists(VariableAccess iterationVariableAccess |
77-
(
78-
iterationVariableAccess =
79-
forLoop.getUpdate().getAChild*().(AssignExpr).getRValue().(AddExpr).getAnOperand() or
80-
iterationVariableAccess =
81-
forLoop.getUpdate().getAChild*().(AssignExpr).getRValue().(SubExpr).getAnOperand()
82-
) and
83-
iterationVariableAccess.getTarget() = getDeclaredVariableInForLoop(forLoop) and
84-
result != iterationVariableAccess
85-
)
69+
result = forLoop.getUpdate().getAChild*().(StepCrementUpdateExpr).getAmountExpr()
8670
}
8771

8872
/**
@@ -194,7 +178,7 @@ private newtype TAlertType =
194178
) {
195179
loopCounterVariable = getDeclaredVariableInForLoop(forLoop) and
196180
variableModifiedInExpression(updateExpr, loopCounterVariable.getAnAccess()) and
197-
not updateExpr instanceof LegacyForLoopUpdateExpression
181+
not updateExpr instanceof StepCrementUpdateExpr
198182
} or
199183
/* 4. The type size of the loop counter is smaller than that of the loop bound. */
200184
TLoopCounterSmallerThanLoopBound(ForStmt forLoop, LegacyForLoopCondition forLoopCondition) {

0 commit comments

Comments
 (0)