@@ -37,13 +37,14 @@ predicate isForLoopWithFloatingPointCounters(ForStmt forLoop, Variable v) {
37
37
* Holds if for loop `forLoop` contains an invalid for loop incrementation.
38
38
* M6-5-2
39
39
*/
40
- predicate isInvalidForLoopIncrementation ( ForStmt forLoop , LoopControlVariable v ) {
41
- v .getAnAccess ( ) = forLoop .getCondition ( ) .getAChild * ( ) and
42
- exists ( VariableAccess va |
43
- va = v .getAnAccess ( ) and
44
- va = forLoop .getUpdate ( ) .getAChild * ( ) and
45
- not exists ( CrementOperation cop | cop .getOperand ( ) = va ) and
46
- not exists ( Call c | c .getQualifier ( ) = va and c .getTarget ( ) instanceof UserCrementOperator )
40
+ predicate isInvalidForLoopIncrementation ( ForStmt forLoop , Variable v , VariableAccess modification ) {
41
+ v = getAnIterationVariable ( forLoop ) and
42
+ modification = v .getAnAccess ( ) and
43
+ modification = forLoop .getUpdate ( ) .getAChild * ( ) and
44
+ modification .isModified ( ) and
45
+ not exists ( CrementOperation cop | cop .getOperand ( ) = modification ) and
46
+ not exists ( Call c |
47
+ c .getQualifier ( ) = modification and c .getTarget ( ) instanceof UserCrementOperator
47
48
) and
48
49
exists ( VariableAccess va | va = forLoop .getCondition ( ) .getAChild * ( ) and va = v .getAnAccess ( ) |
49
50
exists ( EqualityOperation eop | eop .getAnOperand ( ) = va )
@@ -163,26 +164,72 @@ predicate isLoopControlVarModifiedInLoopExpr(
163
164
predicate isNonBoolLoopControlVar (
164
165
ForStmt forLoop , LoopControlVariable loopControlVariable , VariableAccess loopControlVariableAccess
165
166
) {
166
- // get a loop control variable that is not a loop counter
167
- loopControlVariableAccess = loopControlVariable .getVariableAccessInLoop ( forLoop ) and
168
- not loopControlVariable = getAnIterationVariable ( forLoop ) and
169
- loopControlVariableAccess .getEnclosingStmt ( ) = forLoop .getStmt ( ) .getAChild * ( ) and
170
- // filter only loop control variables that are modified
171
- (
172
- loopControlVariableAccess .isModified ( ) or
173
- loopControlVariableAccess .isAddressOfAccess ( )
174
- ) and
175
- // check if the variable type is anything but bool
176
- not loopControlVariable .getType ( ) instanceof BoolType
167
+ exists ( Variable loopCounter , ComparisonOperation terminationCheck |
168
+ loopCounter = getAnIterationVariable ( forLoop ) and
169
+ forLoop .getCondition ( ) = terminationCheck .getParent * ( )
170
+ |
171
+ // get a loop control variable that is not a loop counter
172
+ loopControlVariableAccess = loopControlVariable .getVariableAccessInLoop ( forLoop ) and
173
+ not loopControlVariable = getAnIterationVariable ( forLoop ) and
174
+ // filter only loop control variables that are modified
175
+ (
176
+ loopControlVariableAccess .isModified ( ) or
177
+ loopControlVariableAccess .isAddressOfAccess ( )
178
+ ) and
179
+ // check if the variable type is anything but bool
180
+ not loopControlVariable .getType ( ) instanceof BoolType and
181
+ // check if the control variable is part of the termination check, but is not compared to the loop counter
182
+ terminationCheck .getAnOperand ( ) = loopControlVariable .getAnAccess ( ) .getParent * ( ) and
183
+ not terminationCheck .getAnOperand ( ) = loopCounter .getAnAccess ( ) .getParent * ( )
184
+ )
177
185
}
178
186
179
- predicate isInvalidLoop ( ForStmt forLoop ) {
180
- isInvalidForLoopIncrementation ( forLoop , _) or
181
- isForLoopWithMulipleCounters ( forLoop ) or
182
- isForLoopWithFloatingPointCounters ( forLoop , _) or
183
- isLoopCounterModifiedInCondition ( forLoop , _) or
184
- isLoopCounterModifiedInStatement ( forLoop , _, _) or
185
- isIrregularLoopCounterModification ( forLoop , _, _) or
186
- isLoopControlVarModifiedInLoopExpr ( forLoop , _, _) or
187
- isNonBoolLoopControlVar ( forLoop , _, _)
187
+ predicate isInvalidLoop ( ForStmt forLoop ) { isInvalidLoop ( forLoop , _, _, _) }
188
+
189
+ predicate isInvalidLoop ( ForStmt forLoop , string reason , Locatable reasonLocation , string reasonLabel ) {
190
+ exists ( Variable loopCounter |
191
+ isInvalidForLoopIncrementation ( forLoop , loopCounter , reasonLocation ) and
192
+ reason =
193
+ "it $@ its loop counter '" + loopCounter .getName ( ) +
194
+ "' with an operation that is not an increment or decrement" and
195
+ reasonLabel = "updates"
196
+ )
197
+ or
198
+ isForLoopWithMulipleCounters ( forLoop ) and
199
+ reason = "it uses multiple loop counters$@" and
200
+ reasonLabel = "" and
201
+ reasonLocation .getLocation ( ) instanceof UnknownExprLocation
202
+ or
203
+ isForLoopWithFloatingPointCounters ( forLoop , reasonLocation ) and
204
+ reason = "it uses a loop counter '$@' of type floating-point" and
205
+ reasonLabel = reasonLocation .( Variable ) .getName ( )
206
+ or
207
+ isLoopCounterModifiedInCondition ( forLoop , reasonLocation ) and
208
+ reason =
209
+ "it $@ the loop counter '" + reasonLocation .( VariableAccess ) .getTarget ( ) .getName ( ) +
210
+ "' in the condition" and
211
+ reasonLabel = "updates"
212
+ or
213
+ exists ( Variable loopCounter |
214
+ isLoopCounterModifiedInStatement ( forLoop , loopCounter , reasonLocation ) and
215
+ reason = "it $@ the loop counter '" + loopCounter .getName ( ) + "' in the body of the loop" and
216
+ reasonLabel = "updates"
217
+ )
218
+ or
219
+ exists ( Variable loopCounter |
220
+ isIrregularLoopCounterModification ( forLoop , loopCounter , reasonLocation ) and
221
+ reason = "it $@ the loop counter '" + loopCounter .getName ( ) + "' irregularly" and
222
+ reasonLabel = "updates"
223
+ )
224
+ or
225
+ exists ( Variable loopControlVariable |
226
+ isLoopControlVarModifiedInLoopExpr ( forLoop , loopControlVariable , reasonLocation ) and
227
+ reason =
228
+ "it updates $@, a loop control variable other than the loop counter, in the update expression of the loop" and
229
+ reasonLabel = loopControlVariable .getName ( )
230
+ )
231
+ or
232
+ isNonBoolLoopControlVar ( forLoop , reasonLocation , _) and
233
+ reason = "its $@ is not a boolean" and
234
+ reasonLabel = "loop control variable"
188
235
}
0 commit comments