Skip to content

Commit 6ffd229

Browse files
committed
Expose mutating / assignment rhs expressions
1 parent 15be010 commit 6ffd229

File tree

2 files changed

+122
-97
lines changed

2 files changed

+122
-97
lines changed

cpp/misra/src/rules/RULE-9-5-1/LegacyForStatementsShouldBeSimple.ql

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ Expr getLoopStepOfForStmt(ForStmt forLoop) {
8383
* limitations.
8484
*/
8585
predicate loopVariableAssignedToNonConstPointerOrReferenceType(
86-
ForStmt forLoop, VariableAccess loopVariableAccessInCondition
86+
ForStmt forLoop, VariableAccess loopVariableAccessInCondition, Expr assignmentRhs
8787
) {
88-
exists(Expr assignmentRhs, Type targetType, DerivedType strippedType |
88+
exists(Type targetType, DerivedType strippedType |
8989
isAssignment(assignmentRhs, targetType, _) and
9090
strippedType = targetType.stripTopLevelSpecifiers() and
9191
not strippedType.getBaseType().isConst() and
@@ -124,11 +124,12 @@ predicate loopVariableAssignedToNonConstPointerOrReferenceType(
124124
* Also, this predicate requires that the call is the body of the given for-loop.
125125
*/
126126
predicate loopVariablePassedAsArgumentToNonConstReferenceParameter(
127-
ForStmt forLoop, VariableAccess loopVariableAccessInCondition
127+
ForStmt forLoop, VariableAccess loopVariableAccessInCondition, Expr loopVariableArgument
128128
) {
129129
exists(Type targetType, ReferenceType strippedReferenceType |
130130
exists(Call call, int i |
131-
call.getArgument(i) = loopVariableAccessInCondition.getTarget().getAnAccess() and
131+
loopVariableArgument = call.getArgument(i) and
132+
loopVariableArgument = loopVariableAccessInCondition.getTarget().getAnAccess() and
132133
call.getEnclosingStmt().getParent*() = forLoop.getStmt() and
133134
strippedReferenceType = targetType.stripTopLevelSpecifiers() and
134135
not strippedReferenceType.getBaseType().isConst()
@@ -168,11 +169,10 @@ private newtype TAlertType =
168169
not condition instanceof LegacyForLoopCondition
169170
} or
170171
/* 3-1. The loop counter is mutated somewhere other than its update expression. */
171-
TLoopCounterMutatedInLoopBody(ForStmt forLoop, Variable loopCounterVariable) {
172+
TLoopCounterMutatedInLoopBody(ForStmt forLoop, Variable loopCounterVariable, Expr mutatingExpr) {
172173
loopCounterVariable = getDeclaredVariableInForLoop(forLoop) and
173-
exists(Expr mutatingExpr | not mutatingExpr = forLoop.getUpdate().getAChild*() |
174-
variableModifiedInExpression(mutatingExpr, loopCounterVariable.getAnAccess())
175-
)
174+
not mutatingExpr = forLoop.getUpdate().getAChild*() and
175+
variableModifiedInExpression(mutatingExpr, loopCounterVariable.getAnAccess())
176176
} or
177177
/* 3-2. The loop counter is not updated using either of `++`, `--`, `+=`, or `-=`. */
178178
TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr(
@@ -255,41 +255,52 @@ private newtype TAlertType =
255255
* 6-1. The loop counter is taken as a mutable reference or its address to a mutable pointer.
256256
*/
257257

258-
TLoopCounterIsTakenNonConstAddress(ForStmt forLoop, VariableAccess loopVariableAccessInCondition) {
258+
TLoopCounterIsTakenNonConstAddress(
259+
ForStmt forLoop, VariableAccess loopVariableAccessInCondition,
260+
Expr loopVariableAccessInAssignment
261+
) {
259262
loopVariableAccessInCondition = forLoop.getCondition().(LegacyForLoopCondition).getLoopCounter() and
260263
(
261-
loopVariableAssignedToNonConstPointerOrReferenceType(forLoop, loopVariableAccessInCondition)
264+
loopVariableAssignedToNonConstPointerOrReferenceType(forLoop, loopVariableAccessInCondition,
265+
loopVariableAccessInAssignment)
262266
or
263267
loopVariablePassedAsArgumentToNonConstReferenceParameter(forLoop,
264-
loopVariableAccessInCondition)
268+
loopVariableAccessInCondition, loopVariableAccessInAssignment)
265269
)
266270
} or
267271
/*
268272
* 6-2. The loop bound is taken as a mutable reference or its address to a mutable pointer.
269273
*/
270274

271-
TLoopBoundIsTakenNonConstAddress(ForStmt forLoop, Expr loopBoundExpr) {
275+
TLoopBoundIsTakenNonConstAddress(
276+
ForStmt forLoop, Expr loopBoundExpr, Expr loopVariableAccessInAssignment
277+
) {
272278
loopBoundExpr = forLoop.getCondition().(LegacyForLoopCondition).getLoopBound() and
273279
exists(VariableAccess variableAccess |
274280
variableAccess = loopBoundExpr.getAChild*() and
275281
(
276-
loopVariableAssignedToNonConstPointerOrReferenceType(forLoop, variableAccess)
282+
loopVariableAssignedToNonConstPointerOrReferenceType(forLoop, variableAccess,
283+
loopVariableAccessInAssignment)
277284
or
278-
loopVariablePassedAsArgumentToNonConstReferenceParameter(forLoop, variableAccess)
285+
loopVariablePassedAsArgumentToNonConstReferenceParameter(forLoop, variableAccess,
286+
loopVariableAccessInAssignment)
279287
)
280288
)
281289
} or
282290
/*
283291
* 6-3. The loop step is taken as a mutable reference or its address to a mutable pointer.
284292
*/
285293

286-
TLoopStepIsTakenNonConstAddress(ForStmt forLoop, Expr loopVariableAccessInCondition) {
294+
TLoopStepIsTakenNonConstAddress(
295+
ForStmt forLoop, Expr loopVariableAccessInCondition, Expr loopVariableAccessInAssignment
296+
) {
287297
loopVariableAccessInCondition = getLoopStepOfForStmt(forLoop) and
288298
(
289-
loopVariableAssignedToNonConstPointerOrReferenceType(forLoop, loopVariableAccessInCondition)
299+
loopVariableAssignedToNonConstPointerOrReferenceType(forLoop, loopVariableAccessInCondition,
300+
loopVariableAccessInAssignment)
290301
or
291302
loopVariablePassedAsArgumentToNonConstReferenceParameter(forLoop,
292-
loopVariableAccessInCondition)
303+
loopVariableAccessInCondition, loopVariableAccessInAssignment)
293304
)
294305
}
295306

@@ -302,16 +313,16 @@ class AlertType extends TAlertType {
302313
Element asElement() {
303314
this = TNonIntegerTypeCounterVariable(result, _) or
304315
this = TNoRelationalOperatorInLoopCondition(result, _) or
305-
this = TLoopCounterMutatedInLoopBody(result, _) or
316+
this = TLoopCounterMutatedInLoopBody(result, _, _) or
306317
this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr(result, _, _) or
307318
this = TLoopCounterSmallerThanLoopBound(result, _) or
308319
this = TLoopBoundIsMutatedVariableAccess(result, _, _) or
309320
this = TLoopBoundIsNonConstExpr(result, _) or
310321
this = TLoopStepIsMutatedVariableAccess(result, _, _) or
311322
this = TLoopStepIsNonConstExpr(result, _) or
312-
this = TLoopCounterIsTakenNonConstAddress(result, _) or
313-
this = TLoopBoundIsTakenNonConstAddress(result, _) or
314-
this = TLoopStepIsTakenNonConstAddress(result, _)
323+
this = TLoopCounterIsTakenNonConstAddress(result, _, _) or
324+
this = TLoopBoundIsTakenNonConstAddress(result, _, _) or
325+
this = TLoopStepIsTakenNonConstAddress(result, _, _)
315326
}
316327

317328
/**
@@ -322,7 +333,7 @@ class AlertType extends TAlertType {
322333
or
323334
this = TNoRelationalOperatorInLoopCondition(_, result)
324335
or
325-
this = TLoopCounterMutatedInLoopBody(_, result)
336+
this = TLoopCounterMutatedInLoopBody(_, result, _)
326337
or
327338
this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr(_, result, _)
328339
or
@@ -339,11 +350,11 @@ class AlertType extends TAlertType {
339350
or
340351
this = TLoopStepIsMutatedVariableAccess(_, result, _)
341352
or
342-
this = TLoopCounterIsTakenNonConstAddress(_, result)
353+
this = TLoopCounterIsTakenNonConstAddress(_, result, _)
343354
or
344-
this = TLoopBoundIsTakenNonConstAddress(_, result)
355+
this = TLoopBoundIsTakenNonConstAddress(_, result, _)
345356
or
346-
this = TLoopStepIsTakenNonConstAddress(_, result)
357+
this = TLoopStepIsTakenNonConstAddress(_, result, _)
347358
}
348359

349360
/**
@@ -356,7 +367,7 @@ class AlertType extends TAlertType {
356367
this = TNoRelationalOperatorInLoopCondition(_, _) and
357368
result = "loop condition"
358369
or
359-
this = TLoopCounterMutatedInLoopBody(_, _) and
370+
this = TLoopCounterMutatedInLoopBody(_, _, _) and
360371
result = "counter variable"
361372
or
362373
this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr(_, _, _) and
@@ -377,13 +388,13 @@ class AlertType extends TAlertType {
377388
this = TLoopStepIsNonConstExpr(_, _) and
378389
result = "loop step"
379390
or
380-
this = TLoopCounterIsTakenNonConstAddress(_, _) and
391+
this = TLoopCounterIsTakenNonConstAddress(_, _, _) and
381392
result = "loop counter"
382393
or
383-
this = TLoopBoundIsTakenNonConstAddress(_, _) and
394+
this = TLoopBoundIsTakenNonConstAddress(_, _, _) and
384395
result = "loop bound"
385396
or
386-
this = TLoopStepIsTakenNonConstAddress(_, _) and
397+
this = TLoopStepIsTakenNonConstAddress(_, _, _) and
387398
result = "loop step"
388399
}
389400

@@ -398,8 +409,8 @@ class AlertType extends TAlertType {
398409
result =
399410
"The $@ does not determine termination based only on a comparison against the value of the counter variable."
400411
or
401-
this = TLoopCounterMutatedInLoopBody(_, _) and
402-
result = "The $@ may be mutated in a location other than its update expression."
412+
this = TLoopCounterMutatedInLoopBody(_, _, _) and
413+
result = "The $@ may be mutated in $@ other than its update expression."
403414
or
404415
this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr(_, _, _) and
405416
result = "The $@ is not updated with an $@ other than addition or subtraction."
@@ -419,22 +430,22 @@ class AlertType extends TAlertType {
419430
this = TLoopStepIsMutatedVariableAccess(_, _, _) and
420431
result = "The $@ is a non-const expression, or a variable that may be $@ in the loop."
421432
or
422-
this = TLoopCounterIsTakenNonConstAddress(_, _) and
423-
result = "The $@ is taken as a mutable reference or its address to a mutable pointer."
433+
this = TLoopCounterIsTakenNonConstAddress(_, _, _) and
434+
result = "The $@ is $@."
424435
or
425-
this = TLoopBoundIsTakenNonConstAddress(_, _) and
426-
result = "The $@ is taken as a mutable reference or its address to a mutable pointer."
436+
this = TLoopBoundIsTakenNonConstAddress(_, _, _) and
437+
result = "The $@ is $@."
427438
or
428-
this = TLoopStepIsTakenNonConstAddress(_, _) and
429-
result = "The $@ is taken as a mutable reference or its address to a mutable pointer."
439+
this = TLoopStepIsTakenNonConstAddress(_, _, _) and
440+
result = "The $@ is $@."
430441
}
431442

432443
Locatable getLinkTarget2() {
433444
this = TNonIntegerTypeCounterVariable(_, result) // Throwaway
434445
or
435446
this = TNoRelationalOperatorInLoopCondition(_, result) // Throwaway
436447
or
437-
this = TLoopCounterMutatedInLoopBody(_, result) // Throwaway
448+
this = TLoopCounterMutatedInLoopBody(_, _, result)
438449
or
439450
this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr(_, _, result)
440451
or
@@ -451,11 +462,11 @@ class AlertType extends TAlertType {
451462
or
452463
this = TLoopStepIsMutatedVariableAccess(_, _, result)
453464
or
454-
this = TLoopCounterIsTakenNonConstAddress(_, result) // Throwaway
465+
this = TLoopCounterIsTakenNonConstAddress(_, _, result)
455466
or
456-
this = TLoopBoundIsTakenNonConstAddress(_, result) // Throwaway
467+
this = TLoopBoundIsTakenNonConstAddress(_, _, result)
457468
or
458-
this = TLoopStepIsTakenNonConstAddress(_, result) // Throwaway
469+
this = TLoopStepIsTakenNonConstAddress(_, _, result)
459470
}
460471

461472
string getLinkText2() {
@@ -465,8 +476,8 @@ class AlertType extends TAlertType {
465476
this = TNoRelationalOperatorInLoopCondition(_, _) and
466477
result = "N/A" // Throwaway
467478
or
468-
this = TLoopCounterMutatedInLoopBody(_, _) and
469-
result = "N/A" // Throwaway
479+
this = TLoopCounterMutatedInLoopBody(_, _, _) and
480+
result = "a location"
470481
or
471482
this = TLoopCounterUpdatedNotByCrementOrAddSubAssignmentExpr(_, _, _) and
472483
result = "expression"
@@ -486,14 +497,14 @@ class AlertType extends TAlertType {
486497
this = TLoopStepIsMutatedVariableAccess(_, _, _) and
487498
result = "mutated"
488499
or
489-
this = TLoopCounterIsTakenNonConstAddress(_, _) and
490-
result = "N/A" // Throwaway
500+
this = TLoopCounterIsTakenNonConstAddress(_, _, _) and
501+
result = "taken as a mutable reference or its address to a mutable pointer"
491502
or
492-
this = TLoopBoundIsTakenNonConstAddress(_, _) and
493-
result = "N/A" // Throwaway
503+
this = TLoopBoundIsTakenNonConstAddress(_, _, _) and
504+
result = "taken as a mutable reference or its address to a mutable pointer"
494505
or
495-
this = TLoopStepIsTakenNonConstAddress(_, _) and
496-
result = "N/A" // Throwaway
506+
this = TLoopStepIsTakenNonConstAddress(_, _, _) and
507+
result = "taken as a mutable reference or its address to a mutable pointer"
497508
}
498509

499510
string toString() { result = this.asElement().toString() }

0 commit comments

Comments
 (0)