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

Commit9830cc0

Browse files
Implement MISRA-C++23 Preprocesser package rules 19-0-4, 19-1-1, and 19-2-1.
1 parenteedca61 commit9830cc0

File tree

34 files changed

+724
-3
lines changed

34 files changed

+724
-3
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
2+
import cpp
3+
import RuleMetadata
4+
import codingstandards.cpp.exclusions.RuleMetadata
5+
6+
newtypePreprocessorQuery=
7+
TUndefOfMacroNotDefinedInFileQuery()or
8+
TInvalidTokenInDefinedOperatorQuery()or
9+
TDefinedOperatorExpandedInIfDirectiveQuery()or
10+
TNoValidIfdefGuardInHeaderQuery()
11+
12+
predicateisPreprocessorQueryMetadata(Queryquery,stringqueryId,stringruleId,stringcategory){
13+
query=
14+
// `Query` instance for the `undefOfMacroNotDefinedInFile` query
15+
PreprocessorPackage::undefOfMacroNotDefinedInFileQuery()and
16+
queryId=
17+
// `@id` for the `undefOfMacroNotDefinedInFile` query
18+
"cpp/misra/undef-of-macro-not-defined-in-file"and
19+
ruleId="RULE-19-0-4"and
20+
category="advisory"
21+
or
22+
query=
23+
// `Query` instance for the `invalidTokenInDefinedOperator` query
24+
PreprocessorPackage::invalidTokenInDefinedOperatorQuery()and
25+
queryId=
26+
// `@id` for the `invalidTokenInDefinedOperator` query
27+
"cpp/misra/invalid-token-in-defined-operator"and
28+
ruleId="RULE-19-1-1"and
29+
category="required"
30+
or
31+
query=
32+
// `Query` instance for the `definedOperatorExpandedInIfDirective` query
33+
PreprocessorPackage::definedOperatorExpandedInIfDirectiveQuery()and
34+
queryId=
35+
// `@id` for the `definedOperatorExpandedInIfDirective` query
36+
"cpp/misra/defined-operator-expanded-in-if-directive"and
37+
ruleId="RULE-19-1-1"and
38+
category="required"
39+
or
40+
query=
41+
// `Query` instance for the `noValidIfdefGuardInHeader` query
42+
PreprocessorPackage::noValidIfdefGuardInHeaderQuery()and
43+
queryId=
44+
// `@id` for the `noValidIfdefGuardInHeader` query
45+
"cpp/misra/no-valid-ifdef-guard-in-header"and
46+
ruleId="RULE-19-2-1"and
47+
category="required"
48+
}
49+
50+
module PreprocessorPackage{
51+
QueryundefOfMacroNotDefinedInFileQuery(){
52+
//autogenerate `Query` type
53+
result=
54+
// `Query` type for `undefOfMacroNotDefinedInFile` query
55+
TQueryCPP(TPreprocessorPackageQuery(TUndefOfMacroNotDefinedInFileQuery()))
56+
}
57+
58+
QueryinvalidTokenInDefinedOperatorQuery(){
59+
//autogenerate `Query` type
60+
result=
61+
// `Query` type for `invalidTokenInDefinedOperator` query
62+
TQueryCPP(TPreprocessorPackageQuery(TInvalidTokenInDefinedOperatorQuery()))
63+
}
64+
65+
QuerydefinedOperatorExpandedInIfDirectiveQuery(){
66+
//autogenerate `Query` type
67+
result=
68+
// `Query` type for `definedOperatorExpandedInIfDirective` query
69+
TQueryCPP(TPreprocessorPackageQuery(TDefinedOperatorExpandedInIfDirectiveQuery()))
70+
}
71+
72+
QuerynoValidIfdefGuardInHeaderQuery(){
73+
//autogenerate `Query` type
74+
result=
75+
// `Query` type for `noValidIfdefGuardInHeader` query
76+
TQueryCPP(TPreprocessorPackageQuery(TNoValidIfdefGuardInHeaderQuery()))
77+
}
78+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import Operators
4040
import OrderOfEvaluation
4141
import OutOfBounds
4242
import Pointers
43+
import Preprocessor
4344
import Representation
4445
import Scope
4546
import SideEffects1
@@ -94,6 +95,7 @@ newtype TCPPQuery =
9495
TOrderOfEvaluationPackageQuery(OrderOfEvaluationQueryq)or
9596
TOutOfBoundsPackageQuery(OutOfBoundsQueryq)or
9697
TPointersPackageQuery(PointersQueryq)or
98+
TPreprocessorPackageQuery(PreprocessorQueryq)or
9799
TRepresentationPackageQuery(RepresentationQueryq)or
98100
TScopePackageQuery(ScopeQueryq)or
99101
TSideEffects1PackageQuery(SideEffects1Queryq)or
@@ -148,6 +150,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
148150
isOrderOfEvaluationQueryMetadata(query,queryId,ruleId,category)or
149151
isOutOfBoundsQueryMetadata(query,queryId,ruleId,category)or
150152
isPointersQueryMetadata(query,queryId,ruleId,category)or
153+
isPreprocessorQueryMetadata(query,queryId,ruleId,category)or
151154
isRepresentationQueryMetadata(query,queryId,ruleId,category)or
152155
isScopeQueryMetadata(query,queryId,ruleId,category)or
153156
isSideEffects1QueryMetadata(query,queryId,ruleId,category)or
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
privateimport codeql.util.DenseRank
2+
3+
/**
4+
* Describes how to construct a condensed list from sparse but orderable data, and how that data
5+
* should be connected, with one such list per specified division.
6+
*/
7+
signaturemodule CondensedListSig{
8+
/**
9+
* The division specifies which items are connected into lists, with one list per division.
10+
*
11+
* For instance, if connecting variables defined in a file, the division will be the file.
12+
*/
13+
classDivision;
14+
15+
/**
16+
* The class of the items to be condensed into lists.
17+
*
18+
* For instance, when connecting variables defined in a file, the items are the variables.
19+
*/
20+
classItem{
21+
stringtoString();
22+
}
23+
24+
/**
25+
* The index specifies the order of the items in the condensed list, and may be sparse (have
26+
* gaps).
27+
*
28+
* For instance, if connecting variables defined in a file, the index will be the line number of
29+
* the variable in the file.
30+
*
31+
* The sparse index (which may have gaps) is used to determine the ordering of the items in the
32+
* condensed list. Once the condensed list is created, the items in the list will automatically be
33+
* assigned a dense index (which has no gaps).
34+
*
35+
* There must be no duplicate indices for the same division for correctness.
36+
*/
37+
intgetSparseIndex(Divisiond,Iteml);
38+
}
39+
40+
/**
41+
* A module to take orderable data (which may not be continuous) and condense it into one or more
42+
* dense lists, with one such list per specified division.
43+
*
44+
* To instantiate this module, you need to provide a `CondensedListSig` module that
45+
* specifies the spare index and division of the items to be connected.
46+
*
47+
* For instance, to create a condensed list of variables defined in every file, you can
48+
* create a `CondensedListSig` module that specifies the file as the division and
49+
* the line number as the sparse index.
50+
*
51+
* ```ql
52+
* module ConfigFileListConfig {
53+
* class Division = File;
54+
* class Item = Variable;
55+
* int getSparseIndex(File file, Variable var) {
56+
* file = var.getLocation().getFile() and
57+
* var.getLocation().getStartLine()
58+
* }
59+
* }
60+
*
61+
* import Condense<ConfigFileListConfig>
62+
*
63+
* from Condense::ListEntry l
64+
* select l, l.getItem(), l.getDenseIndex(), l.getNext(), l.getPrev(),
65+
* ```
66+
*/
67+
module Condense<CondensedListSig Config>{
68+
newtypeTList=
69+
THead(Config::Iteml, Config::Divisiont){denseRank(t,l)=1}or
70+
TCons(ListEntryprev, Config::Iteml){prev.getDenseIndex()=denseRank(prev.getDivision(),l)-1}
71+
72+
privatemodule DenseRankConfigimplementsDenseRankInputSig2{
73+
classRanked= Config::Item;
74+
75+
classC= Config::Division;
76+
77+
predicategetRank= Config::getSparseIndex/2;
78+
}
79+
80+
privateimport DenseRank2<DenseRankConfig>
81+
82+
classListEntryextendsTList{
83+
Config::DivisiongetDivision(){
84+
this=THead(_,result)
85+
or
86+
exists(ListEntryprev|this=TCons(prev, _)andresult=prev.getDivision())
87+
}
88+
89+
stringtoString(){
90+
result=getItem().toString()+" [index "+getDenseIndex()+"]"
91+
}
92+
93+
Config::ItemgetItem(){
94+
this=THead(result, _)
95+
or
96+
this=TCons(_,result)
97+
}
98+
99+
intgetDenseIndex(){
100+
result=denseRank(getDivision(),getItem())
101+
}
102+
103+
ListEntrygetPrev(){this=TCons(result, _)}
104+
105+
ListEntrygetNext(){result.getPrev()=this}
106+
}
107+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
bindingset[this]
2+
signatureclassItemSig{
3+
bindingset[this]
4+
stringtoString();
5+
}
6+
7+
module Pair<ItemSig A,ItemSig B>{
8+
signaturepredicatepred(Aa,Bb);
9+
10+
module Where<pred/2 ctor>{
11+
privatenewtypeTAll=TSome(Aa,Bb){
12+
ctor(a,b)
13+
}
14+
15+
classPairextendsTAll{
16+
AgetFirst(){
17+
this=TSome(result, _)
18+
}
19+
20+
BgetSecond(){
21+
this=TSome(_,result)
22+
}
23+
24+
stringtoString(){
25+
result=getFirst().toString()+", "+getSecond().toString()
26+
}
27+
}
28+
}
29+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* @id cpp/misra/undef-of-macro-not-defined-in-file
3+
* @name RULE-19-0-4: #undef should only be used for macros defined previously in the same file
4+
* @description Using #undef to undefine a macro that is not defined in the same file can lead to
5+
* confusion.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity warning
9+
* @tags external/misra/id/rule-19-0-4
10+
* scope/single-translation-unit
11+
* readability
12+
* maintanability
13+
* external/misra/enforcement/decidable
14+
* external/misra/obligation/advisory
15+
*/
16+
17+
import cpp
18+
import codingstandards.cpp.misra
19+
import codingstandards.cpp.util.CondensedList
20+
import codingstandards.cpp.util.Pair
21+
22+
classDefOrUndefextendsPreprocessorDirective{
23+
stringname;
24+
25+
DefOrUndef(){
26+
name=this.(PreprocessorUndef).getName()or
27+
name=this.(Macro).getName()
28+
}
29+
30+
stringgetName(){result=name}
31+
}
32+
33+
predicaterelevantNameAndFile(stringname,Filefile){
34+
exists(DefOrUndefm|
35+
m.getName()=nameand
36+
m.getFile()=file
37+
)
38+
}
39+
40+
classStringFilePair= Pair<string,File>::Where<relevantNameAndFile/2>::Pair;
41+
42+
module DefUndefListConfigimplementsCondensedListSig{
43+
classDivision=StringFilePair;
44+
45+
classItem=DefOrUndef;
46+
47+
intgetSparseIndex(StringFilePairdivision,DefOrUndefdirective){
48+
directive.getName()=division.getFirst()and
49+
directive.getFile()=division.getSecond()and
50+
result=directive.getLocation().getStartLine()
51+
}
52+
}
53+
54+
classListEntry= Condense<DefUndefListConfig>::ListEntry;
55+
56+
fromPreprocessorUndefundef,ListEntrydefUndefListEntry
57+
where
58+
notisExcluded(undef, PreprocessorPackage::undefOfMacroNotDefinedInFileQuery())and
59+
// There exists a def or undef for a given name and file, and it is an #undef
60+
undef=defUndefListEntry.getItem()and
61+
// Exclude cases where the previous def or undef with the same name in the same file is a #define
62+
notexists(ListEntryprev|
63+
prev=defUndefListEntry.getPrev()and
64+
prev.getItem()instanceofMacro
65+
)
66+
selectundef,"Undef of name '"+undef.getName()+"' not defined in the same file."
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* @id cpp/misra/defined-operator-expanded-in-if-directive
3+
* @name RULE-19-1-1: The defined preprocessor operator shall be used appropriately
4+
* @description Macro expansions that produce the token 'defined' inside of an if directive result
5+
* in undefined behavior.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-19-1-1
10+
* scope/single-translation-unit
11+
* correctness
12+
* maintainability
13+
* external/misra/enforcement/decidable
14+
* external/misra/obligation/required
15+
*/
16+
17+
import cpp
18+
import codingstandards.cpp.misra
19+
20+
fromPreprocessorIfifDirective,MacroInvocationmi
21+
where
22+
notisExcluded(ifDirective, PreprocessorPackage::macroDefinitionContainsDefinedOperatorQuery())and
23+
ifDirective.getLocation().subsumes(mi.getLocation())and
24+
mi.getMacro().getBody().regexpMatch(".*defined.*")
25+
selectifDirective,
26+
"If directive contains macro expansion including the token 'defined' from macro $@, which results in undefined behavior.",
27+
mi.getMacro(),mi.getMacroName()
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @id cpp/misra/invalid-token-in-defined-operator
3+
* @name RULE-19-1-1: The defined preprocessor operator shall be used appropriately
4+
* @description Using the defined operator without an immediately following optionally parenthesized
5+
* identifier results in undefined behavior.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-19-1-1
10+
* scope/single-translation-unit
11+
* correctness
12+
* maintainability
13+
* external/misra/enforcement/decidable
14+
* external/misra/obligation/required
15+
*/
16+
17+
import cpp
18+
import codingstandards.cpp.misra
19+
20+
stringidRegex(){
21+
result="[a-zA-Z_]([a-zA-Z_0-9]*)"
22+
}
23+
24+
bindingset[body]
25+
predicatehasInvalidDefinedOperator(stringbody){
26+
body.regexpMatch(
27+
// Contains text "defined" at a word break
28+
".*\\bdefined"+
29+
// Negative zero width lookahead:
30+
"(?!("+
31+
// (group) optional whitespace followed by a valid identifier
32+
"(\\s*"+idRegex()+")"+
33+
// or
34+
"|"+
35+
// (group) optional whitespace followed by parenthesis and valid identifier
36+
"(\\s*\\(\\s*"+idRegex()+"\\s*\\))"+
37+
// End negative zero width lookahead, match remaining text
38+
")).*")
39+
}
40+
41+
fromPreprocessorIfifDirective
42+
where
43+
notisExcluded(ifDirective, PreprocessorPackage::invalidTokenInDefinedOperatorQuery())and
44+
hasInvalidDefinedOperator(ifDirective.getHead())
45+
selectifDirective,"Invalid use of defined operator in if directive."

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp