Skip to content

Commit 18daff7

Browse files
committed
Introduce newtype
1 parent 5e24d1b commit 18daff7

File tree

1 file changed

+274
-100
lines changed

1 file changed

+274
-100
lines changed

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

Lines changed: 274 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)