-
Notifications
You must be signed in to change notification settings - Fork 75
Package Preprocessor 5 #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 6 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
770ef41
Preprocessor5: add pkg to tasks file
knewbury01 2b0527b
Preprocessor5: add Rule 20-7
knewbury01 3bb8b61
Preprocessor5: add Rule PRE32-C
knewbury01 b68029c
Preprocessor5: fix query formatting
knewbury01 0ece5fe
Preprocessor5: add Rule MSC38-C
knewbury01 2f23d33
Preprocessor5: improve alert message Rule MSC38-C
knewbury01 090f074
Preprocessor5: fix testcase Rule MSC38-C
knewbury01 531b1e6
Preprocessor5: performance improvement PRE32-C
knewbury01 3780d35
Preprocessor5: add implementation notes
knewbury01 515ce63
Add help files for MSC38-C and PRE32-C
mbaluda 22c9e95
Add help files for MSC38-C and PRE32-C
mbaluda 759c9e6
Normalize unicode in help files.
mbaluda e649ef1
Add help files for MSC38-C and PRE32-C
mbaluda fb74797
Merge branch 'main' into knewbury01/Preprocessor5
knewbury01 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
c/cert/src/rules/MSC38-C/DoNotTreatAPredefinedIdentifierAsObject.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # MSC38-C: Do not treat a predefined identifier as an object if it might only be implemented as a macro | ||
|
|
||
| This query implements the CERT-C rule MSC38-C: | ||
|
|
||
| > Do not treat a predefined identifier as an object if it might only be implemented as a macro | ||
|
|
||
| ## CERT | ||
|
|
||
| ** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` ** | ||
|
|
||
| ## Implementation notes | ||
|
|
||
| None | ||
|
|
||
| ## References | ||
|
|
||
| * CERT-C: [MSC38-C: Do not treat a predefined identifier as an object if it might only be implemented as a macro](https://wiki.sei.cmu.edu/confluence/display/c) | ||
45 changes: 45 additions & 0 deletions
45
c/cert/src/rules/MSC38-C/DoNotTreatAPredefinedIdentifierAsObject.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| /** | ||
| * @id c/cert/do-not-treat-a-predefined-identifier-as-object | ||
| * @name MSC38-C: Do not treat a predefined identifier as an object if it might only be implemented as a macro | ||
| * @description Accessing an object or function that expands to one of a few specific standard | ||
| * library macros is undefined behaviour. | ||
| * @kind problem | ||
| * @precision very-high | ||
| * @problem.severity warning | ||
| * @tags external/cert/id/msc38-c | ||
| * correctness | ||
| * readability | ||
| * external/cert/obligation/rule | ||
| */ | ||
|
|
||
| import cpp | ||
| import codingstandards.c.cert | ||
|
|
||
| predicate hasRestrictedMacroName(string s) { | ||
| s = "assert" | ||
| or | ||
| s = "errno" | ||
| or | ||
| s = "math_errhandling" | ||
| or | ||
| s = "setjmp" | ||
| or | ||
| s = "va_arg" | ||
| or | ||
| s = "va_copy" | ||
| or | ||
| s = "va_end" | ||
| or | ||
| s = "va_start" | ||
| } | ||
|
|
||
| from Element m, string name | ||
| where | ||
| not isExcluded(m, Preprocessor5Package::doNotTreatAPredefinedIdentifierAsObjectQuery()) and | ||
| ( | ||
| m.(Access).getTarget().hasName(name) | ||
| or | ||
| m.(Declaration).hasGlobalName(name) | ||
| ) and | ||
| hasRestrictedMacroName(name) | ||
| select m, "Supression of standard library macro " + name + "." |
17 changes: 17 additions & 0 deletions
17
c/cert/src/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # PRE32-C: Do not use preprocessor directives in invocations of function-like macros | ||
|
knewbury01 marked this conversation as resolved.
|
||
|
|
||
| This query implements the CERT-C rule PRE32-C: | ||
|
|
||
| > Do not use preprocessor directives in invocations of function-like macros | ||
|
|
||
| ## CERT | ||
|
|
||
| ** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` ** | ||
|
|
||
| ## Implementation notes | ||
|
|
||
| None | ||
|
|
||
| ## References | ||
|
|
||
| * CERT-C: [PRE32-C: Do not use preprocessor directives in invocations of function-like macros](https://wiki.sei.cmu.edu/confluence/display/c) | ||
58 changes: 58 additions & 0 deletions
58
c/cert/src/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| /** | ||
| * @id c/cert/macro-or-function-args-contain-hash-token | ||
| * @name PRE32-C: Do not use preprocessor directives in invocations of function-like macros | ||
| * @description Arguments to a function-like macros shall not contain tokens that look like | ||
| * pre-processing directives or else behaviour after macro expansion is unpredictable. | ||
| * This rule applies to functions as well in case they are implemented using macros. | ||
| * @kind problem | ||
| * @precision high | ||
| * @problem.severity warning | ||
| * @tags external/cert/id/pre32-c | ||
| * correctness | ||
| * readability | ||
| * external/cert/obligation/rule | ||
| */ | ||
|
|
||
| import cpp | ||
| import codingstandards.c.cert | ||
| import codingstandards.cpp.PreprocessorDirective | ||
|
|
||
| pragma[noinline] | ||
| predicate isFunctionInvocationLocation(FunctionCall call, File f, int startline, int endline) { | ||
| call.getLocation().hasLocationInfo(f.getAbsolutePath(), startline, _, _, _) and | ||
| //for all function calls the closest location heurisitc we have for end line is the next node in cfg | ||
| call.getASuccessor().getLocation().hasLocationInfo(f.getAbsolutePath(), endline, _, _, _) | ||
| } | ||
|
|
||
| PreprocessorDirective isLocatedInAFunctionInvocation(FunctionCall c) { | ||
| exists(PreprocessorDirective p, File f, int startCall, int endCall | | ||
| isFunctionInvocationLocation(c, f, startCall, endCall) and | ||
| exists(int startLine, int endLine | isPreprocDirectiveLine(p, f, startLine, endLine) | | ||
| startCall < startLine and | ||
| startCall < endLine and | ||
| endLine <= endCall and | ||
| endLine <= endCall | ||
| ) and | ||
| result = p | ||
| ) | ||
| } | ||
|
|
||
| from PreprocessorDirective p, string msg | ||
| where | ||
| not isExcluded(p, Preprocessor5Package::macroOrFunctionArgsContainHashTokenQuery()) and | ||
| exists(FunctionCall c | | ||
| p = isLocatedInAFunctionInvocation(c) and | ||
| //if this is actually a function in a macro ignore it because it will still be seen in the macro condition | ||
| not c.isInMacroExpansion() and | ||
| msg = | ||
| "Invocation of function " + c.getTarget().getName() + " includes a token \"" + p + | ||
| "\" that could be confused for an argument preprocessor directive." | ||
| ) | ||
| or | ||
| exists(MacroInvocation m | | ||
| p = isLocatedInAMacroInvocation(m) and | ||
| msg = | ||
| "Invocation of macro " + m.getMacroName() + " includes a token \"" + p + | ||
| "\" that could be confused for an argument preprocessor directive." | ||
| ) | ||
| select p, msg |
2 changes: 2 additions & 0 deletions
2
c/cert/test/rules/MSC38-C/DoNotTreatAPredefinedIdentifierAsObject.expected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| | test.c:3:12:3:16 | errno | Supression of standard library macro errno. | | ||
| | test.c:10:21:10:26 | assert | Supression of standard library macro assert. | |
1 change: 1 addition & 0 deletions
1
c/cert/test/rules/MSC38-C/DoNotTreatAPredefinedIdentifierAsObject.qlref
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| rules/MSC38-C/DoNotTreatAPredefinedIdentifierAsObject.ql |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #include <assert.h> | ||
|
|
||
| extern int errno; // NON_COMPLIANT | ||
|
|
||
| typedef void (*handler_type)(int); | ||
|
|
||
| void execute_handler(handler_type handler, int value) { handler(value); } | ||
|
|
||
| void f(int e) { | ||
| execute_handler(&(assert), e < 0); // NON_COMPLIANT | ||
| } | ||
|
|
||
| static void assert_handler(int value) { assert(value); } | ||
|
|
||
| void f2(int e) { | ||
| execute_handler(&assert_handler, e < 0); // COMPLIANT | ||
| } |
8 changes: 8 additions & 0 deletions
8
c/cert/test/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.expected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| | test.c:9:1:9:19 | #if NOTDEFINEDMACRO | Invocation of macro MACROFUNCTION includes a token "#if NOTDEFINEDMACRO" that could be confused for an argument preprocessor directive. | | ||
| | test.c:11:1:11:5 | #else | Invocation of macro MACROFUNCTION includes a token "#else" that could be confused for an argument preprocessor directive. | | ||
| | test.c:13:1:13:6 | #endif | Invocation of macro MACROFUNCTION includes a token "#endif" that could be confused for an argument preprocessor directive. | | ||
| | test.c:20:1:20:16 | #ifdef SOMEMACRO | Invocation of function memcpy includes a token "#ifdef SOMEMACRO" that could be confused for an argument preprocessor directive. | | ||
| | test.c:22:1:22:5 | #else | Invocation of function memcpy includes a token "#else" that could be confused for an argument preprocessor directive. | | ||
| | test.c:24:1:24:6 | #endif | Invocation of function memcpy includes a token "#endif" that could be confused for an argument preprocessor directive. | | ||
| | test.c:27:1:27:8 | #if TEST | Invocation of function memcpy includes a token "#if TEST" that could be confused for an argument preprocessor directive. | | ||
| | test.c:28:1:28:6 | #endif | Invocation of function memcpy includes a token "#endif" that could be confused for an argument preprocessor directive. | |
1 change: 1 addition & 0 deletions
1
c/cert/test/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.qlref
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| rules/PRE32-C/MacroOrFunctionArgsContainHashToken.ql |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
|
|
||
| #include <string.h> | ||
| #define MACROFUNCTION(X) strlen(X) | ||
|
|
||
| void func(const char *src) { | ||
| char *dest; | ||
|
|
||
| MACROFUNCTION( | ||
| #if NOTDEFINEDMACRO // NON_COMPLIANT | ||
| "longstringtest!test!" | ||
| #else // NON_COMPLIANT | ||
| "shortstring" | ||
| #endif // NON_COMPLIANT | ||
| ); | ||
|
|
||
| MACROFUNCTION("alright"); // COMPLIANT | ||
| memcpy(dest, src, 12); // COMPLIANT | ||
|
|
||
| memcpy(dest, src, | ||
| #ifdef SOMEMACRO // NON_COMPLIANT | ||
| 12 | ||
| #else // NON_COMPLIANT | ||
| 24 | ||
| #endif // NON_COMPLIANT | ||
| ); | ||
|
|
||
| #if TEST // COMPLIANT[FALSE_POSITIVE] | ||
| #endif // COMPLIANT[FALSE_POSITIVE] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
...es/macroparameternotenclosedinparentheses/MacroParameterNotEnclosedInParentheses.expected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| | test.c:1:1:1:27 | #define MACRO(X,Y) (X * Y) | Accesses of parameter 'X' are not always enclosed in parentheses in the macro MACRO. | | ||
| | test.c:1:1:1:27 | #define MACRO(X,Y) (X * Y) | Accesses of parameter 'Y' are not always enclosed in parentheses in the macro MACRO. | | ||
| | test.c:4:1:4:29 | #define MACROFOUR(X,Y) (X).Y | Accesses of parameter 'Y' are not always enclosed in parentheses in the macro MACROFOUR. | |
2 changes: 2 additions & 0 deletions
2
...st/rules/macroparameternotenclosedinparentheses/MacroParameterNotEnclosedInParentheses.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| // GENERATED FILE - DO NOT MODIFY | ||
| import codingstandards.cpp.rules.macroparameternotenclosedinparentheses.MacroParameterNotEnclosedInParentheses |
7 changes: 7 additions & 0 deletions
7
c/common/test/rules/macroparameternotenclosedinparentheses/test.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| #define MACRO(X, Y) (X * Y) // NON_COMPLIANT | ||
| #define MACROTWO(X, Y) ((X) * (Y)) // COMPLIANT | ||
| #define MACROTHREE(X) a##X *(X) // COMPLIANT | ||
| #define MACROFOUR(X, Y) (X).Y // COMPLIANT[FALSE_POSITIVE] | ||
|
|
||
| #define MACROFIVE(Y) MACROSIX(Y) // COMPLIANT | ||
| #define MACROSIX(X) ((X) + 1) // COMPLIANT |
24 changes: 24 additions & 0 deletions
24
c/misra/src/rules/RULE-20-7/MacroParameterNotEnclosedInParenthesesCQuery.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| /** | ||
| * @id c/misra/macro-parameter-not-enclosed-in-parentheses-c-query | ||
| * @name RULE-20-7: Expressions resulting from the expansion of macro parameters shall be enclosed in parentheses | ||
| * @description In the definition of a function-like macro, each instance of a parameter shall be | ||
| * enclosed in parentheses, otherwise the result of preprocessor macro substitition may | ||
| * not be as expected. | ||
| * @kind problem | ||
| * @precision high | ||
| * @problem.severity warning | ||
| * @tags external/misra/id/rule-20-7 | ||
| * correctness | ||
| * readability | ||
| * external/misra/obligation/required | ||
| */ | ||
|
|
||
| import cpp | ||
| import codingstandards.c.misra | ||
| import codingstandards.cpp.rules.macroparameternotenclosedinparentheses.MacroParameterNotEnclosedInParentheses | ||
|
|
||
| class MacroParameterNotEnclosedInParenthesesCQueryQuery extends MacroParameterNotEnclosedInParenthesesSharedQuery { | ||
| MacroParameterNotEnclosedInParenthesesCQueryQuery() { | ||
| this = Preprocessor5Package::macroParameterNotEnclosedInParenthesesCQueryQuery() | ||
| } | ||
| } |
1 change: 1 addition & 0 deletions
1
c/misra/test/rules/RULE-20-7/MacroParameterNotEnclosedInParenthesesCQuery.testref
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| c/common/test/rules/macroparameternotenclosedinparentheses/MacroParameterNotEnclosedInParentheses.ql |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 0 additions & 1 deletion
1
cpp/autosar/test/rules/M16-0-6/FunctionLikeMacroParameterNotEnclosedInParentheses.qlref
This file was deleted.
Oops, something went wrong.
1 change: 1 addition & 0 deletions
1
cpp/autosar/test/rules/M16-0-6/FunctionLikeMacroParameterNotEnclosedInParentheses.testref
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| cpp/common/test/rules/macroparameternotenclosedinparentheses/MacroParameterNotEnclosedInParentheses.ql |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
cpp/common/src/codingstandards/cpp/PreprocessorDirective.qll
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import cpp | ||
| import codingstandards.cpp.Macro | ||
|
|
||
| pragma[noinline] | ||
| predicate isPreprocDirectiveLocation(PreprocessorDirective pd, File f, int startChar) { | ||
| pd.getLocation().charLoc(f, startChar, _) | ||
| } | ||
|
|
||
| pragma[noinline] | ||
| predicate isPreprocDirectiveLine(PreprocessorDirective pd, File f, int startline, int endline) { | ||
| pd.getLocation().hasLocationInfo(f.getAbsolutePath(), startline, _, endline, _) | ||
| } | ||
|
|
||
| PreprocessorDirective isLocatedInAMacroInvocation(MacroInvocation m) { | ||
| exists(PreprocessorDirective p | | ||
| // There is not sufficient information in the database for nested macro invocations, because | ||
| // the location of nested macros and preprocessor directives are all set to the location of the | ||
| // outermost macro invocation | ||
| not exists(m.getParentInvocation()) and | ||
| exists(File f, int startChar, int endChar | | ||
| isMacroInvocationLocation(m, f, startChar, endChar) and | ||
| exists(int lStart | isPreprocDirectiveLocation(p, f, lStart) | | ||
| // If the start location of the preprocessor directive is after the start of the macro | ||
| // invocation, and before the end, it must be within the macro invocation | ||
| // Note: it's critical to use startChar < lStart, not startChar <= lStart, because the | ||
| // latter will include preprocessor directives which occur in nested macro invocations | ||
| startChar < lStart and lStart < endChar | ||
| ) | ||
| ) and | ||
| result = p | ||
| ) | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.