@@ -20,8 +20,13 @@ import semmle.code.cpp.dataflow.internal.AddressFlow
2020import codingstandards.cpp.misra
2121import codingstandards.cpp.Call
2222import codingstandards.cpp.Loops
23+ import codingstandards.cpp.ast.Increment
2324import codingstandards.cpp.misra.BuiltInTypeRules:: MisraCpp23BuiltInTypes
2425
26+ Variable getDeclaredVariableInForLoop ( ForStmt forLoop ) {
27+ result = forLoop .getADeclaration ( ) .getADeclarationEntry ( ) .( VariableDeclarationEntry ) .getVariable ( )
28+ }
29+
2530/**
2631 * Holds if the given expression may mutate the variable.
2732 */
@@ -75,7 +80,7 @@ Expr getLoopStepOfForStmt(ForStmt forLoop) {
7580 iterationVariableAccess =
7681 forLoop .getUpdate ( ) .getAChild * ( ) .( AssignExpr ) .getRValue ( ) .( SubExpr ) .getAnOperand ( )
7782 ) and
78- iterationVariableAccess .getTarget ( ) = forLoop . getAnIterationVariable ( ) and
83+ iterationVariableAccess .getTarget ( ) = getDeclaredVariableInForLoop ( forLoop ) and
7984 result != iterationVariableAccess
8085 )
8186}
@@ -159,9 +164,9 @@ predicate loopVariablePassedAsArgumentToNonConstReferenceParameter(
159164
160165private newtype TAlertType =
161166 /* 1. There is a counter variable that is not of an integer type. */
162- TNonIntegerTypeCounterVariable ( ForStmt forLoop , Variable iterationVariable ) {
163- iterationVariable = forLoop . getAnIterationVariable ( ) and
164- exists ( Type type | type = iterationVariable .getType ( ) |
167+ TNonIntegerTypeCounterVariable ( ForStmt forLoop , Variable loopCounter ) {
168+ loopCounter = getDeclaredVariableInForLoop ( forLoop ) and
169+ exists ( Type type | type = loopCounter .getType ( ) |
165170 not (
166171 type instanceof IntegralType or
167172 type instanceof FixedWidthIntegralType
@@ -178,14 +183,18 @@ private newtype TAlertType =
178183 not condition instanceof LegacyForLoopCondition
179184 } or
180185 /* 3-1. The loop counter is mutated somewhere other than its update expression. */
181- TLoopCounterMutatedInLoopBody ( ForStmt forLoop , Variable loopCounter ) {
182- loopCounter = forLoop . getAnIterationVariable ( ) and
186+ TLoopCounterMutatedInLoopBody ( ForStmt forLoop , Variable loopCounterVariable ) {
187+ loopCounterVariable = getDeclaredVariableInForLoop ( forLoop ) and
183188 variableModifiedInExpression ( forLoop .getStmt ( ) .getChildStmt ( ) .getAChild * ( ) ,
184- loopCounter .getAnAccess ( ) )
189+ loopCounterVariable .getAnAccess ( ) )
185190 } or
186191 /* 3-2. The loop counter is not updated using either of `++`, `--`, `+=`, or `-=`. */
187- TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr ( ForStmt forLoop ) {
188- none ( ) // TODO
192+ TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr (
193+ ForStmt forLoop , Variable loopCounterVariable , Expr updateExpr
194+ ) {
195+ loopCounterVariable = getDeclaredVariableInForLoop ( forLoop ) and
196+ variableModifiedInExpression ( updateExpr , loopCounterVariable .getAnAccess ( ) ) and
197+ not updateExpr instanceof LegacyForLoopUpdateExpression
189198 } or
190199 /* 4. The type size of the loop counter is smaller than that of the loop bound. */
191200 TLoopCounterSmallerThanLoopBound ( ForStmt forLoop , LegacyForLoopCondition forLoopCondition ) {
@@ -281,6 +290,7 @@ class AlertType extends TAlertType {
281290 this = TNonIntegerTypeCounterVariable ( result , _) or
282291 this = TNoRelationalOperatorInLoopCondition ( result , _) or
283292 this = TLoopCounterMutatedInLoopBody ( result , _) or
293+ this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr ( result , _, _) or
284294 this = TLoopCounterSmallerThanLoopBound ( result , _) or
285295 this = TLoopBoundIsMutatedVariableAccess ( result , _, _) or
286296 this = TLoopBoundIsNonConstExpr ( result , _) or
@@ -301,6 +311,8 @@ class AlertType extends TAlertType {
301311 or
302312 this = TLoopCounterMutatedInLoopBody ( _, result )
303313 or
314+ this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr ( _, result , _)
315+ or
304316 exists ( LegacyForLoopCondition forLoopCondition |
305317 this = TLoopCounterSmallerThanLoopBound ( _, forLoopCondition ) and
306318 result = forLoopCondition .getLoopCounter ( )
@@ -334,6 +346,9 @@ class AlertType extends TAlertType {
334346 this = TLoopCounterMutatedInLoopBody ( _, _) and
335347 result = "counter variable"
336348 or
349+ this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr ( _, _, _) and
350+ result = "counter variable"
351+ or
337352 this = TLoopCounterSmallerThanLoopBound ( _, _) and
338353 result = "counter variable"
339354 or
@@ -364,15 +379,18 @@ class AlertType extends TAlertType {
364379 */
365380 string getMessage ( ) {
366381 this = TNonIntegerTypeCounterVariable ( _, _) and
367- result = "The $@ is not of an integer type." // Throwaway placeholder
382+ result = "The $@ is not of an integer type."
368383 or
369384 this = TNoRelationalOperatorInLoopCondition ( _, _) and
370385 result =
371- "The $@ does not compare the counter variable to an expression using a relational operator." // Throwaway placeholder
386+ "The $@ does not compare the counter variable to an expression using a relational operator."
372387 or
373388 this = TLoopCounterMutatedInLoopBody ( _, _) and
374389 result = "The $@ may be mutated in a location other than its update expression."
375390 or
391+ this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr ( _, _, _) and
392+ result = "The $@ is not updated with an $@ other than addition or subtraction."
393+ or
376394 this = TLoopCounterSmallerThanLoopBound ( _, _) and
377395 result = "The $@ has a smaller type than that of the $@."
378396 or
@@ -403,7 +421,9 @@ class AlertType extends TAlertType {
403421 or
404422 this = TNoRelationalOperatorInLoopCondition ( _, result ) // Throwaway
405423 or
406- this = TLoopCounterMutatedInLoopBody ( _, _) // Throwaway
424+ this = TLoopCounterMutatedInLoopBody ( _, result ) // Throwaway
425+ or
426+ this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr ( _, _, result )
407427 or
408428 exists ( LegacyForLoopCondition forLoopCondition |
409429 this = TLoopCounterSmallerThanLoopBound ( _, forLoopCondition ) and
@@ -435,6 +455,9 @@ class AlertType extends TAlertType {
435455 this = TLoopCounterMutatedInLoopBody ( _, _) and
436456 result = "N/A" // Throwaway
437457 or
458+ this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr ( _, _, _) and
459+ result = "expression"
460+ or
438461 this = TLoopCounterSmallerThanLoopBound ( _, _) and
439462 result = "loop bound"
440463 or
0 commit comments