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 {
2010AssignAddOrSubExpr ( ) {
2111this instanceof AssignAddExpr or
2212this 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
3463AddOrSubThenAssignExpr ( ) {
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+ }