Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita612c2c

Browse files
Merge pull request#938 from github/jeongsoolee09/MISRA-C++-2023-Statements
Implement "Statements" package
2 parentsb43fff2 +2163c54 commita612c2c

17 files changed

+1790
-0
lines changed

‎cpp/common/src/codingstandards/cpp/Loops.qll‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,3 +374,40 @@ predicate isInvalidLoop(ForStmt forLoop, string reason, Locatable reasonLocation
374374
reason="its $@ is not a boolean"and
375375
reasonLabel="loop control variable"
376376
}
377+
378+
/**
379+
* A comparison expression that has the minimum qualification as being a valid termination
380+
* condition of a legacy for-loop. It is characterized by a value read from a variable being
381+
* compared to a value, which is supposed to be the loop bound.
382+
*/
383+
classLegacyForLoopConditionextendsRelationalOperation{
384+
/**
385+
* The legacy for-loop this relational operation is a condition of.
386+
*/
387+
ForStmtforLoop;
388+
VariableAccessloopCounter;
389+
ExprloopBound;
390+
391+
LegacyForLoopCondition(){
392+
this=forLoop.getCondition()and
393+
loopCounter=this.getAnOperand()and
394+
loopBound=this.getAnOperand()and
395+
loopCounter.getTarget()=getAnIterationVariable(forLoop)and
396+
loopBound!=loopCounter
397+
}
398+
399+
/**
400+
* Gets the for-loop this expression is a termination condition of.
401+
*/
402+
ForStmtgetForLoop(){result=forLoop}
403+
404+
/**
405+
* Gets the variable access to the loop counter variable, appearing in this loop condition.
406+
*/
407+
VariableAccessgetLoopCounter(){result=loopCounter}
408+
409+
/**
410+
* Gets the variable access to the loop bound variable, appearing in this loop condition.
411+
*/
412+
ExprgetLoopBound(){result=loopBound}
413+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* Provides a library for working with expressions that update the value
3+
* of a numeric variable by incrementing or decrementing it by a certain
4+
* amount.
5+
*/
6+
7+
import cpp
8+
9+
privateclassAssignAddOrSubExprextendsAssignArithmeticOperation{
10+
AssignAddOrSubExpr(){
11+
thisinstanceofAssignAddExpror
12+
thisinstanceofAssignSubExpr
13+
}
14+
}
15+
16+
privateclassAddOrSubExprextendsBinaryArithmeticOperation{
17+
AddOrSubExpr(){
18+
thisinstanceofAddExpror
19+
thisinstanceofSubExpr
20+
}
21+
}
22+
23+
/**
24+
* An expression that updates a numeric variable by adding to or subtracting
25+
* from it a certain amount.
26+
*/
27+
abstractclassStepCrementUpdateExprextendsExpr{
28+
/**
29+
* The expression in the abstract syntax tree that represents the amount of
30+
* value by which the variable is updated.
31+
*/
32+
abstractExprgetAmountExpr();
33+
}
34+
35+
/**
36+
* An increment or decrement operator application, either postfix or prefix.
37+
*/
38+
classPostfixOrPrefixCrementExprextendsCrementOperation,StepCrementUpdateExpr{
39+
overrideExprgetAmountExpr(){none()}
40+
}
41+
42+
/**
43+
* An add-then-assign or subtract-then-assign expression in a shortened form,
44+
* i.e. `+=` or `-=`.
45+
*/
46+
classAssignAddOrSubUpdateExprextendsAssignAddOrSubExpr,StepCrementUpdateExpr{
47+
overrideExprgetAmountExpr(){result=this.getRValue()}
48+
}
49+
50+
/**
51+
* An add-then-assign expression or a subtract-then-assign expression, i.e.
52+
* `x = x + E` or `x = x - E`, where `x` is some variable and `E` an
53+
* arbitrary expression.
54+
*/
55+
classAddOrSubThenAssignExprextendsAssignExpr,StepCrementUpdateExpr{
56+
/** The `x` as in the left-hand side of `x = x + E`. */
57+
VariableAccesslvalueVariable;
58+
/** The `x + E` as in `x = x + E`. */
59+
AddOrSubExpraddOrSubExpr;
60+
/** The `E` as in `x = x + E`. */
61+
ExpramountExpr;
62+
63+
AddOrSubThenAssignExpr(){
64+
this.getLValue()=lvalueVariableand
65+
this.getRValue()=addOrSubExprand
66+
exists(VariableAccesslvalueVariableAsRvalue|
67+
lvalueVariableAsRvalue=addOrSubExpr.getAnOperand()and
68+
amountExpr=addOrSubExpr.getAnOperand()and
69+
lvalueVariableAsRvalue!=amountExpr
70+
|
71+
lvalueVariable.getTarget()=lvalueVariableAsRvalue.(VariableAccess).getTarget()
72+
)
73+
}
74+
75+
overrideExprgetAmountExpr(){result=amountExpr}
76+
}

‎cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import SideEffects1
5050
import SideEffects2
5151
import SmartPointers1
5252
import SmartPointers2
53+
import Statements
5354
import Strings
5455
import Templates
5556
import Toolchain
@@ -108,6 +109,7 @@ newtype TCPPQuery =
108109
TSideEffects2PackageQuery(SideEffects2Queryq)or
109110
TSmartPointers1PackageQuery(SmartPointers1Queryq)or
110111
TSmartPointers2PackageQuery(SmartPointers2Queryq)or
112+
TStatementsPackageQuery(StatementsQueryq)or
111113
TStringsPackageQuery(StringsQueryq)or
112114
TTemplatesPackageQuery(TemplatesQueryq)or
113115
TToolchainPackageQuery(ToolchainQueryq)or
@@ -166,6 +168,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
166168
isSideEffects2QueryMetadata(query,queryId,ruleId,category)or
167169
isSmartPointers1QueryMetadata(query,queryId,ruleId,category)or
168170
isSmartPointers2QueryMetadata(query,queryId,ruleId,category)or
171+
isStatementsQueryMetadata(query,queryId,ruleId,category)or
169172
isStringsQueryMetadata(query,queryId,ruleId,category)or
170173
isTemplatesQueryMetadata(query,queryId,ruleId,category)or
171174
isToolchainQueryMetadata(query,queryId,ruleId,category)or
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
2+
import cpp
3+
import RuleMetadata
4+
import codingstandards.cpp.exclusions.RuleMetadata
5+
6+
newtypeStatementsQuery=
7+
TAppropriateStructureOfSwitchStatementQuery()or
8+
TLegacyForStatementsShouldBeSimpleQuery()or
9+
TForRangeInitializerAtMostOneFunctionCallQuery()
10+
11+
predicateisStatementsQueryMetadata(Queryquery,stringqueryId,stringruleId,stringcategory){
12+
query=
13+
// `Query` instance for the `appropriateStructureOfSwitchStatement` query
14+
StatementsPackage::appropriateStructureOfSwitchStatementQuery()and
15+
queryId=
16+
// `@id` for the `appropriateStructureOfSwitchStatement` query
17+
"cpp/misra/appropriate-structure-of-switch-statement"and
18+
ruleId="RULE-9-4-2"and
19+
category="required"
20+
or
21+
query=
22+
// `Query` instance for the `legacyForStatementsShouldBeSimple` query
23+
StatementsPackage::legacyForStatementsShouldBeSimpleQuery()and
24+
queryId=
25+
// `@id` for the `legacyForStatementsShouldBeSimple` query
26+
"cpp/misra/legacy-for-statements-should-be-simple"and
27+
ruleId="RULE-9-5-1"and
28+
category="advisory"
29+
or
30+
query=
31+
// `Query` instance for the `forRangeInitializerAtMostOneFunctionCall` query
32+
StatementsPackage::forRangeInitializerAtMostOneFunctionCallQuery()and
33+
queryId=
34+
// `@id` for the `forRangeInitializerAtMostOneFunctionCall` query
35+
"cpp/misra/for-range-initializer-at-most-one-function-call"and
36+
ruleId="RULE-9-5-2"and
37+
category="required"
38+
}
39+
40+
module StatementsPackage{
41+
QueryappropriateStructureOfSwitchStatementQuery(){
42+
//autogenerate `Query` type
43+
result=
44+
// `Query` type for `appropriateStructureOfSwitchStatement` query
45+
TQueryCPP(TStatementsPackageQuery(TAppropriateStructureOfSwitchStatementQuery()))
46+
}
47+
48+
QuerylegacyForStatementsShouldBeSimpleQuery(){
49+
//autogenerate `Query` type
50+
result=
51+
// `Query` type for `legacyForStatementsShouldBeSimple` query
52+
TQueryCPP(TStatementsPackageQuery(TLegacyForStatementsShouldBeSimpleQuery()))
53+
}
54+
55+
QueryforRangeInitializerAtMostOneFunctionCallQuery(){
56+
//autogenerate `Query` type
57+
result=
58+
// `Query` type for `forRangeInitializerAtMostOneFunctionCall` query
59+
TQueryCPP(TStatementsPackageQuery(TForRangeInitializerAtMostOneFunctionCallQuery()))
60+
}
61+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/**
2+
* @id cpp/misra/appropriate-structure-of-switch-statement
3+
* @name RULE-9-4-2: The structure of a switch statement shall be appropriate
4+
* @description A switch statement should have an appropriate structure with proper cases, default
5+
* labels, and break statements to ensure clear control flow and prevent unintended
6+
* fall-through behavior.
7+
* @kind problem
8+
* @precision very-high
9+
* @problem.severity error
10+
* @tags external/misra/id/rule-9-4-2
11+
* correctness
12+
* maintainability
13+
* readability
14+
* external/misra/allocated-target/single-translation-unit
15+
* external/misra/enforcement/decidable
16+
* external/misra/obligation/required
17+
*/
18+
19+
import cpp
20+
import codingstandards.cpp.misra
21+
import codingstandards.cpp.SwitchStatement
22+
import codingstandards.cpp.Noreturn
23+
24+
fromSwitchStmtswitch,stringmessage
25+
where
26+
notisExcluded(switch, StatementsPackage::appropriateStructureOfSwitchStatementQuery())and
27+
/* 1. There is a statement that appears as an initializer and is not a declaration statement. */
28+
exists(Stmtinitializer|initializer=switch.getInitialization()|
29+
notinitializerinstanceofDeclStmt
30+
)and
31+
message="contains a statement that is not a simple declaration"
32+
or
33+
/* 2. There is a switch case label that does not lead a branch (i.e. a switch case label is nested). */
34+
exists(SwitchCasecase|case=switch.getASwitchCase()|caseinstanceofNestedSwitchCase)and
35+
message="contains a switch label that is not directly within the switch body"
36+
or
37+
/* 3. There is a non-case label in a label group. */
38+
exists(SwitchCasecase|case=switch.getASwitchCase()|
39+
case.getAStmt().getChildStmt*()instanceofLabelStmt
40+
)and
41+
message="contains a statement label that is not a case label"
42+
or
43+
/* 4. There is a statement before the first case label. */
44+
exists(StmtswitchBody|switchBody=switch.getStmt()|
45+
notswitchBody.getChild(0)instanceofSwitchCase
46+
)and
47+
message="has a statement that is not a case label as its first element"
48+
or
49+
/* 5. There is a switch case whose terminator is not one of the allowed kinds. */
50+
exists(SwitchCasecase,StmtlastStmt|
51+
case=switch.getASwitchCase()andlastStmt=case.getLastStmt()
52+
|
53+
not(
54+
lastStmtinstanceofBreakStmtor
55+
lastStmtinstanceofReturnStmtor
56+
lastStmtinstanceofGotoStmtor
57+
lastStmtinstanceofContinueStmtor
58+
lastStmt.(ExprStmt).getExpr()instanceofThrowExpror
59+
lastStmt.(ExprStmt).getExpr().(Call).getTarget()instanceofNoreturnFunctionor
60+
lastStmt.getAnAttribute().getName().matches("%fallthrough")// We'd like to consider compiler variants such as `clang::fallthrough`.
61+
)
62+
)and
63+
message="is missing a terminator that moves the control out of its body"
64+
or
65+
/* 6. The switch statement does not have more than two unique branches. */
66+
count(SwitchCasecase|
67+
case=switch.getASwitchCase()and
68+
/*
69+
* If the next switch case is the following statement of this switch case, then the two
70+
* switch cases are consecutive and should be considered as constituting one branch
71+
* together.
72+
*/
73+
74+
notcase.getNextSwitchCase()=case.getFollowingStmt()
75+
|
76+
case
77+
)<2and
78+
message="contains less than two branches"
79+
or
80+
/* 7-1. The switch statement is not an enum switch statement and is missing a default case. */
81+
notswitchinstanceofEnumSwitchand
82+
notswitch.hasDefaultCase()and
83+
message="lacks a default case"
84+
or
85+
/*
86+
* 7-2. The switch statement is an enum switch statement and is missing a branch for a
87+
* variant.
88+
*/
89+
90+
exists(switch.(EnumSwitch).getAMissingCase())and
91+
message="lacks a case for one of its variants"
92+
selectswitch,"Switch statement "+message+"."

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp