@@ -164,115 +164,289 @@ predicate loopVariablePassedAsArgumentToNonConstReferenceParameter(
164164 )
165165}
166166
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 ( ) |
173172 not (
174173 type instanceof IntegralType or
175174 type instanceof FixedWidthIntegralType
176175 )
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 * ( )
177213 ) 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 )
180322 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+ }
185327
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"
189334 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"
208337 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+ }
213359
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."
255388 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 ( )
260452
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