@@ -164,115 +164,289 @@ predicate loopVariablePassedAsArgumentToNonConstReferenceParameter(
164
164
)
165
165
}
166
166
167
- from ForStmt forLoop , Locatable forLoopExpr , string message
168
- where
169
- not isExcluded ( forLoop , StatementsPackage:: legacyForStatementsShouldBeSimpleQuery ( ) ) and
170
- (
171
- /* 1. There is a counter variable that is not of an integer type. */
172
- exists ( Type type | type = forLoop .getAnIterationVariable ( ) .getType ( ) |
167
+ private newtype TAlertType =
168
+ /* 1. There is a counter variable that is not of an integer type. */
169
+ TNonIntegerTypeCounterVariable ( ForStmt forLoop , Variable iterationVariable ) {
170
+ iterationVariable = forLoop .getAnIterationVariable ( ) and
171
+ exists ( Type type | type = iterationVariable .getType ( ) |
173
172
not (
174
173
type instanceof IntegralType or
175
174
type instanceof FixedWidthIntegralType
176
175
)
176
+ )
177
+ } or
178
+ /*
179
+ * 2. The loop condition checks termination without comparing the counter variable to the
180
+ * loop bound using a relational operator.
181
+ */
182
+
183
+ TNoRelationalOperatorInLoopCondition ( ForStmt forLoop , Expr condition ) {
184
+ condition = forLoop .getCondition ( ) and
185
+ not condition instanceof LegacyForLoopCondition
186
+ } or
187
+ /* 3. The loop counter is mutated somewhere other than its update expression. */
188
+ TLoopCounterMutatedInLoopBody ( ForStmt forLoop , Variable loopCounter ) {
189
+ isIrregularLoopCounterModification ( forLoop , loopCounter , loopCounter .getAnAccess ( ) )
190
+ } or
191
+ /* 4. The type size of the loop counter is smaller than that of the loop bound. */
192
+ TLoopCounterSmallerThanLoopBound ( ForStmt forLoop , LegacyForLoopCondition forLoopCondition ) {
193
+ forLoopCondition = forLoop .getCondition ( ) and
194
+ exists ( Type loopCounterType , Type loopBoundType |
195
+ loopCounterType = forLoopCondition .getLoopCounter ( ) .getType ( ) and
196
+ loopBoundType = forLoopCondition .getLoopBound ( ) .getType ( )
197
+ |
198
+ loopCounterType .getSize ( ) < loopBoundType .getSize ( )
199
+ )
200
+ } or
201
+ /*
202
+ * 5-1. The loop bound is a non-const expression, or a variable that is mutated in the for loop.
203
+ */
204
+
205
+ TLoopBoundIsNonConstExprOrMutatedVariableAccess ( ForStmt forLoop , Expr loopBound , Expr mutatingExpr ) {
206
+ loopBound = forLoop .getCondition ( ) .( LegacyForLoopCondition ) .getLoopBound ( ) and
207
+ (
208
+ /* The mutating expression may be in the loop body. */
209
+ mutatingExpr = forLoop .getStmt ( ) .getChildStmt ( ) .getAChild * ( )
210
+ or
211
+ /* The mutating expression may be in the loop updating expression. */
212
+ mutatingExpr = forLoop .getUpdate ( ) .getAChild * ( )
177
213
) and
178
- forLoopExpr = forLoop .getAnIterationVariable ( ) and
179
- message = "The counter variable is not of an integer type."
214
+ /* 5-1-1. The loop bound is a variable that is mutated in the for loop. */
215
+ (
216
+ variableModifiedInExpression ( mutatingExpr ,
217
+ loopBound .( VariableAccess ) .getTarget ( ) .getAnAccess ( ) )
218
+ or
219
+ /* 5-1-2. The loop bound is not a variable access nor a constant expression. */
220
+ not loopBound instanceof VariableAccess and not loopBound .isConstant ( )
221
+ )
222
+ } or
223
+ /*
224
+ * 5-2. The loop step is a non-const expression, or are variable that is mutated in the for loop.
225
+ */
226
+
227
+ TLoopStepIsNonConstExprOrMutatedVariableAccess ( ForStmt forLoop , Expr loopStep , Expr mutatingExpr ) {
228
+ loopStep = getLoopStepOfForStmt ( forLoop ) and
229
+ (
230
+ /* The mutating expression may be in the loop body. */
231
+ mutatingExpr = forLoop .getStmt ( ) .getChildStmt ( ) .getAChild * ( )
232
+ or
233
+ /* The mutating expression may be in the loop updating expression. */
234
+ mutatingExpr = forLoop .getUpdate ( ) .getAChild * ( )
235
+ ) and
236
+ (
237
+ /* 5-2-2. The loop step is a variable that is mutated in the for loop. */
238
+ variableModifiedInExpression ( mutatingExpr , loopStep .( VariableAccess ) .getTarget ( ) .getAnAccess ( ) )
239
+ or
240
+ /* 5-2-2. The loop step is not a variable access nor a constant expression. */
241
+ not loopStep instanceof VariableAccess and not loopStep .isConstant ( )
242
+ )
243
+ } or
244
+ /*
245
+ * 6-1. The loop counter is taken as a mutable reference or its address to a mutable pointer.
246
+ */
247
+
248
+ TLoopCounterIsTakenNonConstAddress ( ForStmt forLoop , VariableAccess loopVariableAccessInCondition ) {
249
+ loopVariableAccessInCondition = forLoop .getCondition ( ) .( LegacyForLoopCondition ) .getLoopCounter ( ) and
250
+ (
251
+ loopVariableAssignedToNonConstPointerOrReferenceType ( forLoop , loopVariableAccessInCondition )
252
+ or
253
+ loopVariablePassedAsArgumentToNonConstReferenceParameter ( forLoop ,
254
+ loopVariableAccessInCondition )
255
+ )
256
+ } or
257
+ /*
258
+ * 6-2. The loop bound is taken as a mutable reference or its address to a mutable pointer.
259
+ */
260
+
261
+ TLoopBoundIsTakenNonConstAddress ( ForStmt forLoop , Expr loopVariableAccessInCondition ) {
262
+ loopVariableAccessInCondition = forLoop .getCondition ( ) .( LegacyForLoopCondition ) .getLoopBound ( ) and
263
+ (
264
+ loopVariableAssignedToNonConstPointerOrReferenceType ( forLoop , loopVariableAccessInCondition )
265
+ or
266
+ loopVariablePassedAsArgumentToNonConstReferenceParameter ( forLoop ,
267
+ loopVariableAccessInCondition )
268
+ )
269
+ } or
270
+ /*
271
+ * 6-3. The loop step is taken as a mutable reference or its address to a mutable pointer.
272
+ */
273
+
274
+ TLoopStepIsTakenNonConstAddress ( ForStmt forLoop , Expr loopVariableAccessInCondition ) {
275
+ loopVariableAccessInCondition = getLoopStepOfForStmt ( forLoop ) and
276
+ (
277
+ loopVariableAssignedToNonConstPointerOrReferenceType ( forLoop , loopVariableAccessInCondition )
278
+ or
279
+ loopVariablePassedAsArgumentToNonConstReferenceParameter ( forLoop ,
280
+ loopVariableAccessInCondition )
281
+ )
282
+ }
283
+
284
+ class AlertType extends TAlertType {
285
+ /**
286
+ * Extract the primary location depending on the case of this instance.
287
+ */
288
+ Location getLocation ( ) { result = this .asElement ( ) .getLocation ( ) }
289
+
290
+ Element asElement ( ) {
291
+ this = TNonIntegerTypeCounterVariable ( result , _) or
292
+ this = TNoRelationalOperatorInLoopCondition ( result , _) or
293
+ this = TLoopCounterMutatedInLoopBody ( result , _) or
294
+ this = TLoopCounterSmallerThanLoopBound ( result , _) or
295
+ this = TLoopBoundIsNonConstExprOrMutatedVariableAccess ( result , _, _) or
296
+ this = TLoopStepIsNonConstExprOrMutatedVariableAccess ( result , _, _) or
297
+ this = TLoopCounterIsTakenNonConstAddress ( result , _) or
298
+ this = TLoopBoundIsTakenNonConstAddress ( result , _) or
299
+ this = TLoopStepIsTakenNonConstAddress ( result , _)
300
+ }
301
+
302
+ /**
303
+ * Gets the target the link leads to depending on the case of this instance.
304
+ */
305
+ Locatable getLinkTarget1 ( ) {
306
+ this = TNonIntegerTypeCounterVariable ( _, result )
307
+ or
308
+ this = TNoRelationalOperatorInLoopCondition ( _, result )
309
+ or
310
+ this = TLoopCounterMutatedInLoopBody ( _, result )
311
+ or
312
+ exists ( LegacyForLoopCondition forLoopCondition |
313
+ this = TLoopCounterSmallerThanLoopBound ( _, forLoopCondition ) and
314
+ result = forLoopCondition .getLoopCounter ( )
315
+ )
316
+ or
317
+ this = TLoopBoundIsNonConstExprOrMutatedVariableAccess ( _, result , _)
318
+ or
319
+ this = TLoopStepIsNonConstExprOrMutatedVariableAccess ( _, result , _)
320
+ or
321
+ this = TLoopCounterIsTakenNonConstAddress ( _, result )
180
322
or
181
- /*
182
- * 2. The loop condition checks termination without comparing the counter variable to the
183
- * loop bound using a relational operator.
184
- */
323
+ this = TLoopBoundIsTakenNonConstAddress ( _ , result )
324
+ or
325
+ this = TLoopStepIsTakenNonConstAddress ( _ , result )
326
+ }
185
327
186
- not forLoop .getCondition ( ) instanceof LegacyForLoopCondition and
187
- forLoopExpr = forLoop .getCondition ( ) and
188
- message = "TODO"
328
+ /**
329
+ * Gets the text of the link depending on the case of this instance.
330
+ */
331
+ string getLinkText1 ( ) {
332
+ this = TNonIntegerTypeCounterVariable ( _, _) and
333
+ result = "counter variable"
189
334
or
190
- /* 3. The loop counter is mutated somewhere other than its update expression. */
191
- exists ( Variable loopCounter |
192
- isIrregularLoopCounterModification ( forLoop , loopCounter , loopCounter .getAnAccess ( ) )
193
- ) and
194
- forLoopExpr = forLoop .getCondition ( ) .( LegacyForLoopCondition ) .getLoopCounter ( ) and
195
- message = "TODO"
196
- or
197
- /* 4. The type size of the loop counter is not greater or equal to that of the loop counter. */
198
- exists ( LegacyForLoopCondition forLoopCondition | forLoopCondition = forLoop .getCondition ( ) |
199
- exists ( Type loopCounterType , Type loopBoundType |
200
- loopCounterType = forLoopCondition .getLoopCounter ( ) .getType ( ) and
201
- loopBoundType = forLoopCondition .getLoopBound ( ) .getType ( )
202
- |
203
- loopCounterType .getSize ( ) < loopBoundType .getSize ( )
204
- )
205
- ) and
206
- forLoopExpr = forLoop .getCondition ( ) and
207
- message = "TODO"
335
+ this = TNoRelationalOperatorInLoopCondition ( _, _) and
336
+ result = "loop condition"
208
337
or
209
- /*
210
- * 5. The loop bound and the loop step are non-const expressions, or are variables that are
211
- * mutated in the for loop.
212
- */
338
+ this = TLoopCounterMutatedInLoopBody ( _, _) and
339
+ result = "counter variable"
340
+ or
341
+ this = TLoopCounterSmallerThanLoopBound ( _, _) and
342
+ result = "counter variable"
343
+ or
344
+ this = TLoopBoundIsNonConstExprOrMutatedVariableAccess ( _, _, _) and
345
+ result = "loop bound"
346
+ or
347
+ this = TLoopStepIsNonConstExprOrMutatedVariableAccess ( _, _, _) and
348
+ result = "loop step"
349
+ or
350
+ this = TLoopCounterIsTakenNonConstAddress ( _, _) and
351
+ result = "loop counter"
352
+ or
353
+ this = TLoopBoundIsTakenNonConstAddress ( _, _) and
354
+ result = "loop bound"
355
+ or
356
+ this = TLoopStepIsTakenNonConstAddress ( _, _) and
357
+ result = "loop step"
358
+ }
213
359
214
- /* 5-1. The mutating expression mutates the loop bound. */
215
- exists ( Expr loopBound |
216
- loopBound = forLoop .getCondition ( ) .( LegacyForLoopCondition ) .getLoopBound ( )
217
- |
218
- exists ( Expr mutatingExpr |
219
- /* The mutating expression may be in the loop body. */
220
- mutatingExpr = forLoop .getStmt ( ) .getChildStmt ( ) .getAChild * ( )
221
- or
222
- /* The mutating expression may be in the loop updating expression. */
223
- mutatingExpr = forLoop .getUpdate ( ) .getAChild * ( )
224
- |
225
- /* 5-1-1. The loop bound is a variable that is mutated in the for loop. */
226
- variableModifiedInExpression ( mutatingExpr ,
227
- loopBound .( VariableAccess ) .getTarget ( ) .getAnAccess ( ) )
228
- or
229
- /* 5-1-2. The loop bound is not a variable access and is not a constant expression. */
230
- not loopBound instanceof VariableAccess and not loopBound .isConstant ( )
231
- )
232
- ) and
233
- forLoopExpr = forLoop .getCondition ( ) .( LegacyForLoopCondition ) .getLoopBound ( ) and
234
- message = "TODO"
235
- or
236
- /* 5-2. The mutating expression mutates the loop step. */
237
- exists ( Expr loopStep | loopStep = getLoopStepOfForStmt ( forLoop ) |
238
- exists ( Expr mutatingExpr |
239
- /* The mutating expression may be in the loop body. */
240
- mutatingExpr = forLoop .getStmt ( ) .getChildStmt ( ) .getAChild * ( )
241
- or
242
- /* The mutating expression may be in the loop updating expression. */
243
- mutatingExpr = forLoop .getUpdate ( ) .getAChild * ( )
244
- |
245
- /* 5-1-2. The loop step is a variable that is mutated in the for loop. */
246
- variableModifiedInExpression ( mutatingExpr ,
247
- loopStep .( VariableAccess ) .getTarget ( ) .getAnAccess ( ) )
248
- or
249
- /* 5-1-2. The loop bound is not a variable access and is not a constant expression. */
250
- not loopStep instanceof VariableAccess and not loopStep .isConstant ( )
251
- )
252
- ) and
253
- forLoopExpr = getLoopStepOfForStmt ( forLoop ) and
254
- message = "TODO"
360
+ /**
361
+ * Gets the message with a placeholder, depending on the case of this instance.
362
+ */
363
+ string getMessage ( ) {
364
+ this = TNonIntegerTypeCounterVariable ( _, _) and
365
+ result = "The $@ is not of an integer type." // Throwaway placeholder
366
+ or
367
+ this = TNoRelationalOperatorInLoopCondition ( _, _) and
368
+ result =
369
+ "The $@ does not compare the counter variable to an expression using a relational operator." // Throwaway placeholder
370
+ or
371
+ this = TLoopCounterMutatedInLoopBody ( _, _) and
372
+ result = "The $@ may be mutated in a location other than its update expression."
373
+ or
374
+ this = TLoopCounterSmallerThanLoopBound ( _, _) and
375
+ result = "The $@ has a smaller type than that of the $@."
376
+ or
377
+ this = TLoopBoundIsNonConstExprOrMutatedVariableAccess ( _, _, _) and
378
+ result = "The $@ is a non-const expression, or a variable that is $@ in the loop."
379
+ or
380
+ this = TLoopStepIsNonConstExprOrMutatedVariableAccess ( _, _, _) and
381
+ result = "The $@ is a non-const expression, or a variable that is $@ in the loop."
382
+ or
383
+ this = TLoopCounterIsTakenNonConstAddress ( _, _) and
384
+ result = "The $@ is taken as a mutable reference or its address to a mutable pointer."
385
+ or
386
+ this = TLoopBoundIsTakenNonConstAddress ( _, _) and
387
+ result = "The $@ is taken as a mutable reference or its address to a mutable pointer."
255
388
or
256
- /*
257
- * 6. Any of the loop counter, loop bound, or a loop step is taken as a mutable reference
258
- * or its address to a mutable pointer.
259
- */
389
+ this = TLoopStepIsTakenNonConstAddress ( _, _) and
390
+ result = "The $@ is taken as a mutable reference or its address to a mutable pointer."
391
+ }
392
+
393
+ Locatable getLinkTarget2 ( ) {
394
+ this = TNonIntegerTypeCounterVariable ( _, result ) // Throwaway
395
+ or
396
+ this = TNoRelationalOperatorInLoopCondition ( _, result ) // Throwaway
397
+ or
398
+ this = TLoopCounterMutatedInLoopBody ( _, _) // Throwaway
399
+ or
400
+ exists ( LegacyForLoopCondition forLoopCondition |
401
+ this = TLoopCounterSmallerThanLoopBound ( _, forLoopCondition ) and
402
+ result = forLoopCondition .getLoopBound ( )
403
+ )
404
+ or
405
+ this = TLoopBoundIsNonConstExprOrMutatedVariableAccess ( _, _, result )
406
+ or
407
+ this = TLoopStepIsNonConstExprOrMutatedVariableAccess ( _, _, result )
408
+ or
409
+ this = TLoopCounterIsTakenNonConstAddress ( _, result ) // Throwaway
410
+ or
411
+ this = TLoopBoundIsTakenNonConstAddress ( _, result ) // Throwaway
412
+ or
413
+ this = TLoopStepIsTakenNonConstAddress ( _, result ) // Throwaway
414
+ }
415
+
416
+ string getLinkText2 ( ) {
417
+ this = TNonIntegerTypeCounterVariable ( _, _) and
418
+ result = "N/A" // Throwaway
419
+ or
420
+ this = TNoRelationalOperatorInLoopCondition ( _, _) and
421
+ result = "N/A" // Throwaway
422
+ or
423
+ this = TLoopCounterMutatedInLoopBody ( _, _) and
424
+ result = "N/A" // Throwaway
425
+ or
426
+ this = TLoopCounterSmallerThanLoopBound ( _, _) and
427
+ result = "loop bound"
428
+ or
429
+ this = TLoopBoundIsNonConstExprOrMutatedVariableAccess ( _, _, _) and
430
+ result = "mutated"
431
+ or
432
+ this = TLoopStepIsNonConstExprOrMutatedVariableAccess ( _, _, _) and
433
+ result = "mutated"
434
+ or
435
+ this = TLoopCounterIsTakenNonConstAddress ( _, _) and
436
+ result = "N/A" // Throwaway
437
+ or
438
+ this = TLoopBoundIsTakenNonConstAddress ( _, _) and
439
+ result = "N/A" // Throwaway
440
+ or
441
+ this = TLoopStepIsTakenNonConstAddress ( _, _) and
442
+ result = "N/A" // Throwaway
443
+ }
444
+
445
+ string toString ( ) { result = this .asElement ( ) .toString ( ) }
446
+ }
447
+
448
+ from AlertType alert
449
+ where not isExcluded ( alert .asElement ( ) , StatementsPackage:: legacyForStatementsShouldBeSimpleQuery ( ) )
450
+ select alert , alert .getMessage ( ) , alert .getLinkTarget1 ( ) , alert .getLinkText1 ( ) ,
451
+ alert .getLinkTarget2 ( ) , alert .getLinkText2 ( )
260
452
261
- exists ( VariableAccess loopVariableAccessInCondition |
262
- (
263
- loopVariableAccessInCondition =
264
- forLoop .getCondition ( ) .( LegacyForLoopCondition ) .getLoopCounter ( ) or
265
- loopVariableAccessInCondition =
266
- forLoop .getCondition ( ) .( LegacyForLoopCondition ) .getLoopBound ( ) or
267
- loopVariableAccessInCondition = getLoopStepOfForStmt ( forLoop )
268
- ) and
269
- (
270
- loopVariableAssignedToNonConstPointerOrReferenceType ( forLoop , loopVariableAccessInCondition )
271
- or
272
- loopVariablePassedAsArgumentToNonConstReferenceParameter ( forLoop ,
273
- loopVariableAccessInCondition )
274
- )
275
- ) and
276
- message = "TODO"
277
- )
278
- select forLoop , message , forLoopExpr , "???"
0 commit comments