Skip to content

Commit 99c5762

Browse files
author
Nikita Kraiouchkine
authored
Merge pull request #17 from knewbury01/knewbury01/Preprocessor4
Add Preprocessor 4 package
2 parents 9346222 + 4779867 commit 99c5762

28 files changed

+411
-38
lines changed

.vscode/tasks.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,11 @@
221221
"Pointers",
222222
"Preprocessor1",
223223
"Preprocessor2",
224+
"Preprocessor3",
225+
"Preprocessor4",
224226
"IntegerConversion",
225227
"Expressions",
226-
"DeadCode"
228+
"DeadCode",
227229
"VirtualFunctions"
228230
]
229231
},
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import cpp
2+
3+
/** Module to reason about keywords in standards C90, C99 and C11. */
4+
module Keywords {
5+
/** Holds if `s` is a keyword. */
6+
predicate isKeyword(string s) {
7+
s = "auto"
8+
or
9+
s = "break"
10+
or
11+
s = "case"
12+
or
13+
s = "char"
14+
or
15+
s = "const"
16+
or
17+
s = "continue"
18+
or
19+
s = "default"
20+
or
21+
s = "do"
22+
or
23+
s = "double"
24+
or
25+
s = "else"
26+
or
27+
s = "enum"
28+
or
29+
s = "extern"
30+
or
31+
s = "float"
32+
or
33+
s = "for"
34+
or
35+
s = "goto"
36+
or
37+
s = "if"
38+
or
39+
s = "inline"
40+
or
41+
s = "int"
42+
or
43+
s = "long"
44+
or
45+
s = "register"
46+
or
47+
s = "restrict"
48+
or
49+
s = "return"
50+
or
51+
s = "short"
52+
or
53+
s = "signed"
54+
or
55+
s = "sizeof"
56+
or
57+
s = "static"
58+
or
59+
s = "struct"
60+
or
61+
s = "switch"
62+
or
63+
s = "typedef"
64+
or
65+
s = "union"
66+
or
67+
s = "unsigned"
68+
or
69+
s = "void"
70+
or
71+
s = "volatile"
72+
or
73+
s = "while"
74+
or
75+
s = "_Alignas"
76+
or
77+
s = "_Alignof"
78+
or
79+
s = "_Atomic"
80+
or
81+
s = "_Bool"
82+
or
83+
s = "_Complex"
84+
or
85+
s = "_Generic"
86+
or
87+
s = "_Imaginary"
88+
or
89+
s = "_Noreturn"
90+
or
91+
s = "_Static_assert"
92+
or
93+
s = "_Thread_local"
94+
}
95+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| test.c:5:3:11:3 | MACROFUNCTION(X) | Invocation of macro MACROFUNCTION includes a token "#else" that could be confused for an argument preprocessor directive. |
2+
| test.c:5:3:11:3 | MACROFUNCTION(X) | Invocation of macro MACROFUNCTION includes a token "#endif" that could be confused for an argument preprocessor directive. |
3+
| test.c:5:3:11:3 | MACROFUNCTION(X) | Invocation of macro MACROFUNCTION includes a token "#if NOTDEFINEDMACRO" that could be confused for an argument preprocessor directive. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.preprocessingdirectivewithinmacroargument.PreprocessingDirectiveWithinMacroArgument
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <string.h>
2+
#define MACROFUNCTION(X) strlen(X)
3+
4+
void f() {
5+
MACROFUNCTION(
6+
#if NOTDEFINEDMACRO // NON_COMPLIANT
7+
"longstringtest!test!"
8+
#else // NON_COMPLIANT
9+
"shortstring"
10+
#endif // NON_COMPLIANT
11+
);
12+
13+
MACROFUNCTION("alright"); // COMPLIANT
14+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @id c/misra/macro-defined-with-the-same-name-as-keyword
3+
* @name RULE-20-4: A macro shall not be defined with the same name as a keyword
4+
* @description Redefinition of keywords is confusing and in the case where the standard library is
5+
* included where that keyword is defined, the redefinition will result in undefined
6+
* behaviour.
7+
* @kind problem
8+
* @precision very-high
9+
* @problem.severity warning
10+
* @tags external/misra/id/rule-20-4
11+
* correctness
12+
* readability
13+
* maintainability
14+
* external/misra/obligation/required
15+
*/
16+
17+
import cpp
18+
import codingstandards.c.misra
19+
import codingstandards.c.Keywords
20+
21+
from Macro m, string name
22+
where
23+
not isExcluded(m, Preprocessor4Package::macroDefinedWithTheSameNameAsKeywordQuery()) and
24+
m.hasName(name) and
25+
Keywords::isKeyword(name)
26+
select m, "Redefinition of keyword '" + name + "'."
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @id c/misra/function-like-macro-args-contain-hash-token-c-query
3+
* @name RULE-20-6: Tokens that look like a preprocessing directive shall not occur within a macro argument
4+
* @description Arguments to a function-like macro shall not contain tokens that look like
5+
* pre-processing directives or else behaviour after macro expansion is unpredictable.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity warning
9+
* @tags external/misra/id/rule-20-6
10+
* readability
11+
* correctness
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
import codingstandards.cpp.rules.preprocessingdirectivewithinmacroargument.PreprocessingDirectiveWithinMacroArgument
18+
19+
class FunctionLikeMacroArgsContainHashTokenCQueryQuery extends PreprocessingDirectiveWithinMacroArgumentSharedQuery {
20+
FunctionLikeMacroArgsContainHashTokenCQueryQuery() {
21+
this = Preprocessor4Package::functionLikeMacroArgsContainHashTokenCQueryQuery()
22+
}
23+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* @id c/misra/define-and-undef-used-on-reserved-identifier-or-macro-name
3+
* @name RULE-21-1: #define and #undef shall not be used on a reserved identifier or reserved macro name
4+
* @description The use of #define and #undef on reserved identifiers or macro names can result in
5+
* undefined behaviour.
6+
* @kind problem
7+
* @precision high
8+
* @problem.severity warning
9+
* @tags external/misra/id/rule-21-1
10+
* correctness
11+
* readability
12+
* maintainability
13+
* external/misra/obligation/required
14+
*/
15+
16+
import cpp
17+
import codingstandards.c.misra
18+
import codingstandards.cpp.Naming
19+
20+
from PreprocessorDirective p, string name
21+
where
22+
not isExcluded(p, Preprocessor4Package::defineAndUndefUsedOnReservedIdentifierOrMacroNameQuery()) and
23+
(
24+
p.(Macro).hasName(name)
25+
or
26+
p.(PreprocessorUndef).getName() = name
27+
) and
28+
(
29+
Naming::Cpp14::hasStandardLibraryMacroName(name)
30+
or
31+
Naming::Cpp14::hasStandardLibraryObjectName(name)
32+
or
33+
name.regexpMatch("_.*")
34+
or
35+
name = "defined"
36+
)
37+
select p, "Reserved identifier '" + name + "' has been undefined or redefined."
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| test.c:1:1:1:16 | #define int long | Redefinition of keyword 'int'. |
2+
| test.c:2:1:2:30 | #define while (E) for (; (E);) | Redefinition of keyword 'while'. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-20-4/MacroDefinedWithTheSameNameAsKeyword.ql

c/misra/test/rules/RULE-20-4/test.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#define int long // NON_COMPLIANT
2+
#define while (E) for (; (E);) // NON_COMPLIANT
3+
#define test(E) for (; (E);) // COMPLIANT
4+
#define _Decimal128 long // COMPLIANT introduced in C23
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/preprocessingdirectivewithinmacroargument/PreprocessingDirectiveWithinMacroArgument.ql
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.c:1:1:1:17 | #define _NOT_OKAY | Reserved identifier '_NOT_OKAY' has been undefined or redefined. |
2+
| test.c:2:1:2:16 | #undef _NOT_OKAY | Reserved identifier '_NOT_OKAY' has been undefined or redefined. |
3+
| test.c:4:1:4:15 | #define defined | Reserved identifier 'defined' has been undefined or redefined. |
4+
| test.c:5:1:5:13 | #define errno | Reserved identifier 'errno' has been undefined or redefined. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-21-1/DefineAndUndefUsedOnReservedIdentifierOrMacroName.ql

c/misra/test/rules/RULE-21-1/test.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#define _NOT_OKAY // NON_COMPLIANT
2+
#undef _NOT_OKAY // NON_COMPLIANT
3+
4+
#define defined // NON_COMPLIANT
5+
#define errno // NON_COMPLIANT
6+
7+
#define NDEBUG 1 // COMPLIANT

cpp/autosar/src/rules/M16-0-5/FunctionLikeMacroArgsContainHashToken.ql

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,10 @@
1616

1717
import cpp
1818
import codingstandards.cpp.autosar
19+
import codingstandards.cpp.rules.preprocessingdirectivewithinmacroargument.PreprocessingDirectiveWithinMacroArgument
1920

20-
pragma[noinline]
21-
predicate isMacroInvocationLocation(MacroInvocation mi, File f, int startChar, int endChar) {
22-
mi.getActualLocation().charLoc(f, startChar, endChar)
21+
class FunctionLikeMacroArgsContainHashTokenCQueryQuery extends PreprocessingDirectiveWithinMacroArgumentSharedQuery {
22+
FunctionLikeMacroArgsContainHashTokenCQueryQuery() {
23+
this = MacrosPackage::functionLikeMacroArgsContainHashTokenQuery()
24+
}
2325
}
24-
25-
pragma[noinline]
26-
predicate isPreprocDirectiveLocation(PreprocessorDirective pd, File f, int startChar) {
27-
pd.getLocation().charLoc(f, startChar, _)
28-
}
29-
30-
from MacroInvocation m, PreprocessorDirective p
31-
where
32-
not isExcluded(m, MacrosPackage::functionLikeMacroArgsContainHashTokenQuery()) and
33-
// There is not sufficient information in the database for nested macro invocations, because
34-
// the location of nested macros and preprocessor directives are all set to the location of the
35-
// outermost macro invocation
36-
not exists(m.getParentInvocation()) and
37-
exists(File f, int startChar, int endChar |
38-
isMacroInvocationLocation(m, f, startChar, endChar) and
39-
exists(int lStart | isPreprocDirectiveLocation(p, f, lStart) |
40-
// If the start location of the preprocessor directive is after the start of the macro
41-
// invocation, and before the end, it must be within the macro invocation
42-
// Note: it's critical to use startChar < lStart, not startChar <= lStart, because the
43-
// latter will include preprocessor directives which occur in nested macro invocations
44-
startChar < lStart and lStart < endChar
45-
)
46-
)
47-
select m,
48-
"Invocation of macro " + m.getMacroName() +
49-
" includes a $@ that could be confused for an argument", p, "preprocessor directive"

cpp/autosar/test/rules/M16-0-5/FunctionLikeMacroArgsContainHashToken.expected

Lines changed: 0 additions & 3 deletions
This file was deleted.

cpp/autosar/test/rules/M16-0-5/FunctionLikeMacroArgsContainHashToken.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp/common/test/rules/preprocessingdirectivewithinmacroargument/PreprocessingDirectiveWithinMacroArgument.ql
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
2+
import cpp
3+
import RuleMetadata
4+
import codingstandards.cpp.exclusions.RuleMetadata
5+
6+
newtype Preprocessor4Query =
7+
TMacroDefinedWithTheSameNameAsKeywordQuery() or
8+
TFunctionLikeMacroArgsContainHashTokenCQueryQuery() or
9+
TDefineAndUndefUsedOnReservedIdentifierOrMacroNameQuery()
10+
11+
predicate isPreprocessor4QueryMetadata(Query query, string queryId, string ruleId) {
12+
query =
13+
// `Query` instance for the `macroDefinedWithTheSameNameAsKeyword` query
14+
Preprocessor4Package::macroDefinedWithTheSameNameAsKeywordQuery() and
15+
queryId =
16+
// `@id` for the `macroDefinedWithTheSameNameAsKeyword` query
17+
"c/misra/macro-defined-with-the-same-name-as-keyword" and
18+
ruleId = "RULE-20-4"
19+
or
20+
query =
21+
// `Query` instance for the `functionLikeMacroArgsContainHashTokenCQuery` query
22+
Preprocessor4Package::functionLikeMacroArgsContainHashTokenCQueryQuery() and
23+
queryId =
24+
// `@id` for the `functionLikeMacroArgsContainHashTokenCQuery` query
25+
"c/misra/function-like-macro-args-contain-hash-token-c-query" and
26+
ruleId = "RULE-20-6"
27+
or
28+
query =
29+
// `Query` instance for the `defineAndUndefUsedOnReservedIdentifierOrMacroName` query
30+
Preprocessor4Package::defineAndUndefUsedOnReservedIdentifierOrMacroNameQuery() and
31+
queryId =
32+
// `@id` for the `defineAndUndefUsedOnReservedIdentifierOrMacroName` query
33+
"c/misra/define-and-undef-used-on-reserved-identifier-or-macro-name" and
34+
ruleId = "RULE-21-1"
35+
}
36+
37+
module Preprocessor4Package {
38+
Query macroDefinedWithTheSameNameAsKeywordQuery() {
39+
//autogenerate `Query` type
40+
result =
41+
// `Query` type for `macroDefinedWithTheSameNameAsKeyword` query
42+
TQueryC(TPreprocessor4PackageQuery(TMacroDefinedWithTheSameNameAsKeywordQuery()))
43+
}
44+
45+
Query functionLikeMacroArgsContainHashTokenCQueryQuery() {
46+
//autogenerate `Query` type
47+
result =
48+
// `Query` type for `functionLikeMacroArgsContainHashTokenCQuery` query
49+
TQueryC(TPreprocessor4PackageQuery(TFunctionLikeMacroArgsContainHashTokenCQueryQuery()))
50+
}
51+
52+
Query defineAndUndefUsedOnReservedIdentifierOrMacroNameQuery() {
53+
//autogenerate `Query` type
54+
result =
55+
// `Query` type for `defineAndUndefUsedOnReservedIdentifierOrMacroName` query
56+
TQueryC(TPreprocessor4PackageQuery(TDefineAndUndefUsedOnReservedIdentifierOrMacroNameQuery()))
57+
}
58+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Pointers1
1111
import Preprocessor1
1212
import Preprocessor2
1313
import Preprocessor3
14+
import Preprocessor4
1415
import SideEffects1
1516
import SideEffects2
1617
import Strings1
@@ -29,6 +30,7 @@ newtype TCQuery =
2930
TPreprocessor1PackageQuery(Preprocessor1Query q) or
3031
TPreprocessor2PackageQuery(Preprocessor2Query q) or
3132
TPreprocessor3PackageQuery(Preprocessor3Query q) or
33+
TPreprocessor4PackageQuery(Preprocessor4Query q) or
3234
TSideEffects1PackageQuery(SideEffects1Query q) or
3335
TSideEffects2PackageQuery(SideEffects2Query q) or
3436
TStrings1PackageQuery(Strings1Query q) or
@@ -47,6 +49,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId) {
4749
isPreprocessor1QueryMetadata(query, queryId, ruleId) or
4850
isPreprocessor2QueryMetadata(query, queryId, ruleId) or
4951
isPreprocessor3QueryMetadata(query, queryId, ruleId) or
52+
isPreprocessor4QueryMetadata(query, queryId, ruleId) or
5053
isSideEffects1QueryMetadata(query, queryId, ruleId) or
5154
isSideEffects2QueryMetadata(query, queryId, ruleId) or
5255
isStrings1QueryMetadata(query, queryId, ruleId) or

0 commit comments

Comments
 (0)