From e8ecc1bb9f98741b1c13ecbdabc8de68580890e2 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Tue, 2 Aug 2022 16:48:43 -0400 Subject: [PATCH 01/24] Declarations1: add pkg to tasks file --- .vscode/tasks.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index baca12d448..508588a175 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -180,6 +180,7 @@ "Const", "DeadCode", "Declarations", + "Declarations1", "Exceptions1", "Exceptions2", "Expressions", From 516b086cd7f9d5bd6b0ceb095ce8b18675d175d7 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Wed, 3 Aug 2022 14:57:08 -0400 Subject: [PATCH 02/24] Declarations1: add rule DCL37-C --- ...DoNotDeclareOrDefineAReservedIdentifier.md | 17 ++++++++ ...DoNotDeclareOrDefineAReservedIdentifier.ql | 40 +++++++++++++++++++ ...eclareOrDefineAReservedIdentifier.expected | 5 +++ ...otDeclareOrDefineAReservedIdentifier.qlref | 1 + c/cert/test/rules/DCL37-C/test.c | 24 +++++++++++ .../cpp/exclusions/c/Declarations1.qll | 25 ++++++++++++ .../cpp/exclusions/c/RuleMetadata.qll | 3 ++ rule_packages/c/Declarations1.json | 29 ++++++++++++++ rules.csv | 2 +- 9 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md create mode 100644 c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.ql create mode 100644 c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.expected create mode 100644 c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.qlref create mode 100644 c/cert/test/rules/DCL37-C/test.c create mode 100644 cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll create mode 100644 rule_packages/c/Declarations1.json diff --git a/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md new file mode 100644 index 0000000000..ad885f216c --- /dev/null +++ b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md @@ -0,0 +1,17 @@ +# DCL37-C: Do not declare or define a reserved identifier + +This query implements the CERT-C rule DCL37-C: + +> Do not declare or define a reserved identifier + +## CERT + +** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` ** + +## Implementation notes + +None + +## References + +* CERT-C: [DCL37-C: Do not declare or define a reserved identifier](https://wiki.sei.cmu.edu/confluence/display/c) diff --git a/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.ql b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.ql new file mode 100644 index 0000000000..6e931c1ede --- /dev/null +++ b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.ql @@ -0,0 +1,40 @@ +/** + * @id c/cert/do-not-declare-or-define-a-reserved-identifier + * @name DCL37-C: Do not declare or define a reserved identifier + * @description Declaring a reserved identifier can lead to undefined behaviour. + * @kind problem + * @precision very-high + * @problem.severity warning + * @tags external/cert/id/dcl37-c + * correctness + * maintainability + * readability + * external/cert/obligation/rule + */ + +import cpp +import codingstandards.c.cert +import codingstandards.cpp.Naming +import codingstandards.c.Keywords + +from Element m, string name +where + not isExcluded(m, Declarations1Package::doNotDeclareOrDefineAReservedIdentifierQuery()) and + ( + m.(Macro).hasName(name) or + m.(Declaration).hasGlobalName(name) + ) and + ( + Naming::Cpp14::hasStandardLibraryMacroName(name) + or + Naming::Cpp14::hasStandardLibraryObjectName(name) + or + Naming::Cpp14::hasStandardLibraryFunctionName(name) + or + name.regexpMatch("_[A-Z_].*") + or + name.regexpMatch("_.*") and m.(Declaration).hasGlobalName(name) + or + Keywords::isKeyword(name) + ) +select m, "Reserved identifier '" + name + "' is declared." diff --git a/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.expected b/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.expected new file mode 100644 index 0000000000..585c6d4c94 --- /dev/null +++ b/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.expected @@ -0,0 +1,5 @@ +| test.c:2:1:2:23 | #define _RESERVED_MACRO | Reserved identifier '_RESERVED_MACRO' is declared. | +| test.c:11:8:11:9 | _s | Reserved identifier '_s' is declared. | +| test.c:15:6:15:7 | _f | Reserved identifier '_f' is declared. | +| test.c:19:7:19:12 | malloc | Reserved identifier 'malloc' is declared. | +| test.c:24:12:24:16 | errno | Reserved identifier 'errno' is declared. | diff --git a/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.qlref b/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.qlref new file mode 100644 index 0000000000..40ad8eb138 --- /dev/null +++ b/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.qlref @@ -0,0 +1 @@ +rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.ql \ No newline at end of file diff --git a/c/cert/test/rules/DCL37-C/test.c b/c/cert/test/rules/DCL37-C/test.c new file mode 100644 index 0000000000..1580dfc6d7 --- /dev/null +++ b/c/cert/test/rules/DCL37-C/test.c @@ -0,0 +1,24 @@ +#ifndef _RESERVED_MACRO +#define _RESERVED_MACRO // NON_COMPLIANT +#endif /* _RESERVED_MACRO */ + +#ifndef _not_reserved_MACRO +#define _not_reserved_MACRO // COMPLIANT +#endif /* _not_reserved_MACRO */ + +static const int INT_LIMIT_MAX = 12000; // COMPLIANT future library directions + +struct _s { // NON_COMPLIANT + struct _s *_next; // COMPLIANT not file scope +}; + +void _f() { // NON_COMPLIANT + int _p; // COMPLIANT not file scope +} + +void *malloc(int bytes) { // NON_COMPLIANT + void *ptr; + return ptr; +} + +extern int errno; // NON_COMPLIANT \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll new file mode 100644 index 0000000000..0650044330 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll @@ -0,0 +1,25 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Declarations1Query = TDoNotDeclareOrDefineAReservedIdentifierQuery() + +predicate isDeclarations1QueryMetadata(Query query, string queryId, string ruleId) { + query = + // `Query` instance for the `doNotDeclareOrDefineAReservedIdentifier` query + Declarations1Package::doNotDeclareOrDefineAReservedIdentifierQuery() and + queryId = + // `@id` for the `doNotDeclareOrDefineAReservedIdentifier` query + "c/cert/do-not-declare-or-define-a-reserved-identifier" and + ruleId = "DCL37-C" +} + +module Declarations1Package { + Query doNotDeclareOrDefineAReservedIdentifierQuery() { + //autogenerate `Query` type + result = + // `Query` type for `doNotDeclareOrDefineAReservedIdentifier` query + TQueryC(TDeclarations1PackageQuery(TDoNotDeclareOrDefineAReservedIdentifierQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll index d4813a7e58..e8bf584d6c 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll @@ -5,6 +5,7 @@ import codingstandards.cpp.exclusions.RuleMetadata import Banned import Concurrency1 import Concurrency2 +import Declarations1 import IO1 import IO2 import IO3 @@ -27,6 +28,7 @@ newtype TCQuery = TBannedPackageQuery(BannedQuery q) or TConcurrency1PackageQuery(Concurrency1Query q) or TConcurrency2PackageQuery(Concurrency2Query q) or + TDeclarations1PackageQuery(Declarations1Query q) or TIO1PackageQuery(IO1Query q) or TIO2PackageQuery(IO2Query q) or TIO3PackageQuery(IO3Query q) or @@ -49,6 +51,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId) { isBannedQueryMetadata(query, queryId, ruleId) or isConcurrency1QueryMetadata(query, queryId, ruleId) or isConcurrency2QueryMetadata(query, queryId, ruleId) or + isDeclarations1QueryMetadata(query, queryId, ruleId) or isIO1QueryMetadata(query, queryId, ruleId) or isIO2QueryMetadata(query, queryId, ruleId) or isIO3QueryMetadata(query, queryId, ruleId) or diff --git a/rule_packages/c/Declarations1.json b/rule_packages/c/Declarations1.json new file mode 100644 index 0000000000..da68fa6052 --- /dev/null +++ b/rule_packages/c/Declarations1.json @@ -0,0 +1,29 @@ +{ + "CERT-C": { + "DCL37-C": { + "properties": { + "obligation": "rule" + }, + "queries": [ + { + "description": "Declaring a reserved identifier can lead to undefined behaviour.", + "kind": "problem", + "name": "Do not declare or define a reserved identifier", + "precision": "very-high", + "severity": "warning", + "short_name": "DoNotDeclareOrDefineAReservedIdentifier", + "tags": [ + "correctness", + "maintainability", + "readability" + ], + "implementation_scope": { + "description": "This query does not consider identifiers described in the future library directions section of the standard. This query also checks for any reserved identifier as declared regardless of whether its header file is included or not.", + "items": [] + } + } + ], + "title": "Do not declare or define a reserved identifier" + } + } +} \ No newline at end of file diff --git a/rules.csv b/rules.csv index 44d2dcf85a..e6b2c258a9 100755 --- a/rules.csv +++ b/rules.csv @@ -501,7 +501,7 @@ c,CERT-C,CON43-C,OutOfScope,Rule,,,Do not allow data races in multithreaded code c,CERT-C,DCL30-C,Yes,Rule,,,Declare objects with appropriate storage durations,,Declarations,Hard, c,CERT-C,DCL31-C,Yes,Rule,,,Declare identifiers before using them,,Declarations,Medium, c,CERT-C,DCL36-C,Yes,Rule,,,Do not declare an identifier with conflicting linkage classifications,,Declarations,Medium, -c,CERT-C,DCL37-C,Yes,Rule,,,Do not declare or define a reserved identifier,,Declarations,Easy, +c,CERT-C,DCL37-C,Yes,Rule,,,Do not declare or define a reserved identifier,,Declarations1,Easy, c,CERT-C,DCL38-C,Yes,Rule,,,Use the correct syntax when declaring a flexible array member,,Declarations,Easy, c,CERT-C,DCL39-C,Yes,Rule,,,Avoid information leakage when passing a structure across a trust boundary,,Declarations,Hard, c,CERT-C,DCL40-C,Yes,Rule,,,Do not create incompatible declarations of the same function or object,,Declarations,Hard, From 110f211c9d7b67d4822d08f05ea2ab462a68c004 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Wed, 3 Aug 2022 16:51:25 -0400 Subject: [PATCH 03/24] Declarations1: add rule DCL31-C --- .../DeclareIdentifiersBeforeUsingThem.md | 18 ++++++++++++++ .../DeclareIdentifiersBeforeUsingThem.ql | 21 ++++++++++++++++ ...DeclareIdentifiersBeforeUsingThem.expected | 2 ++ .../DeclareIdentifiersBeforeUsingThem.qlref | 1 + c/cert/test/rules/DCL31-C/test.c | 12 ++++++++++ .../cpp/exclusions/c/Declarations1.qll | 19 ++++++++++++++- rule_packages/c/Declarations1.json | 24 +++++++++++++++++++ rules.csv | 2 +- 8 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md create mode 100644 c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql create mode 100644 c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected create mode 100644 c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.qlref create mode 100644 c/cert/test/rules/DCL31-C/test.c diff --git a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md new file mode 100644 index 0000000000..68103aa881 --- /dev/null +++ b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md @@ -0,0 +1,18 @@ +# DCL31-C: Declare identifiers before using them + +This query implements the CERT-C rule DCL31-C: + +> Declare identifiers before using them + + +## CERT + +** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` ** + +## Implementation notes + +This query does not check for implicit function declarations as this is partially compiler checked. + +## References + +* CERT-C: [DCL31-C: Declare identifiers before using them](https://wiki.sei.cmu.edu/confluence/display/c) diff --git a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql new file mode 100644 index 0000000000..add104c51c --- /dev/null +++ b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql @@ -0,0 +1,21 @@ +/** + * @id c/cert/declare-identifiers-before-using-them + * @name DCL31-C: Declare identifiers before using them + * @description Omission of type specifiers may not be supported by some compilers. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/cert/id/dcl31-c + * correctness + * readability + * external/cert/obligation/rule + */ + +import cpp +import codingstandards.c.cert + +from Declaration d +where + not isExcluded(d, Declarations1Package::declareIdentifiersBeforeUsingThemQuery()) and + exists(Specifier s | s = d.getASpecifier() and s.toString().regexpMatch("implicit_.*")) +select d, "Declaration is missing a type specifier." diff --git a/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected b/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected new file mode 100644 index 0000000000..d109ec77f4 --- /dev/null +++ b/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected @@ -0,0 +1,2 @@ +| test.c:2:8:2:8 | g | Declaration is missing a type specifier. | +| test.c:6:1:6:1 | f | Declaration is missing a type specifier. | diff --git a/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.qlref b/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.qlref new file mode 100644 index 0000000000..f51571a4fe --- /dev/null +++ b/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.qlref @@ -0,0 +1 @@ +rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql \ No newline at end of file diff --git a/c/cert/test/rules/DCL31-C/test.c b/c/cert/test/rules/DCL31-C/test.c new file mode 100644 index 0000000000..0b3201bf35 --- /dev/null +++ b/c/cert/test/rules/DCL31-C/test.c @@ -0,0 +1,12 @@ + +extern g; //NON_COMPLIANT + +extern int g1; //COMPLIANT + +f(void) { //NON_COMPLIANT + return 1; +} + +int f1(void) { //COMPLIANT + return 1; +} \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll index 0650044330..d2551a7cb9 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll @@ -3,9 +3,19 @@ import cpp import RuleMetadata import codingstandards.cpp.exclusions.RuleMetadata -newtype Declarations1Query = TDoNotDeclareOrDefineAReservedIdentifierQuery() +newtype Declarations1Query = + TDeclareIdentifiersBeforeUsingThemQuery() or + TDoNotDeclareOrDefineAReservedIdentifierQuery() predicate isDeclarations1QueryMetadata(Query query, string queryId, string ruleId) { + query = + // `Query` instance for the `declareIdentifiersBeforeUsingThem` query + Declarations1Package::declareIdentifiersBeforeUsingThemQuery() and + queryId = + // `@id` for the `declareIdentifiersBeforeUsingThem` query + "c/cert/declare-identifiers-before-using-them" and + ruleId = "DCL31-C" + or query = // `Query` instance for the `doNotDeclareOrDefineAReservedIdentifier` query Declarations1Package::doNotDeclareOrDefineAReservedIdentifierQuery() and @@ -16,6 +26,13 @@ predicate isDeclarations1QueryMetadata(Query query, string queryId, string ruleI } module Declarations1Package { + Query declareIdentifiersBeforeUsingThemQuery() { + //autogenerate `Query` type + result = + // `Query` type for `declareIdentifiersBeforeUsingThem` query + TQueryC(TDeclarations1PackageQuery(TDeclareIdentifiersBeforeUsingThemQuery())) + } + Query doNotDeclareOrDefineAReservedIdentifierQuery() { //autogenerate `Query` type result = diff --git a/rule_packages/c/Declarations1.json b/rule_packages/c/Declarations1.json index da68fa6052..2ca9f836bd 100644 --- a/rule_packages/c/Declarations1.json +++ b/rule_packages/c/Declarations1.json @@ -1,5 +1,29 @@ { "CERT-C": { + "DCL31-C": { + "properties": { + "obligation": "rule" + }, + "queries": [ + { + "description": "Omission of type specifiers may not be supported by some compilers.", + "kind": "problem", + "name": "Declare identifiers before using them", + "precision": "very-high", + "severity": "error", + "short_name": "DeclareIdentifiersBeforeUsingThem", + "tags": [ + "correctness", + "readability" + ], + "implementation_scope": { + "description": "This query does not check for implicit function declarations as this is partially compiler checked.", + "items": [] + } + } + ], + "title": "Declare identifiers before using them" + }, "DCL37-C": { "properties": { "obligation": "rule" diff --git a/rules.csv b/rules.csv index e6b2c258a9..8343e34230 100755 --- a/rules.csv +++ b/rules.csv @@ -499,7 +499,7 @@ c,CERT-C,CON40-C,Yes,Rule,,,Do not refer to an atomic variable twice in an expre c,CERT-C,CON41-C,Yes,Rule,,,Wrap functions that can fail spuriously in a loop,CON53-CPP,Concurrency3,Medium, c,CERT-C,CON43-C,OutOfScope,Rule,,,Do not allow data races in multithreaded code,,,, c,CERT-C,DCL30-C,Yes,Rule,,,Declare objects with appropriate storage durations,,Declarations,Hard, -c,CERT-C,DCL31-C,Yes,Rule,,,Declare identifiers before using them,,Declarations,Medium, +c,CERT-C,DCL31-C,Yes,Rule,,,Declare identifiers before using them,,Declarations1,Medium, c,CERT-C,DCL36-C,Yes,Rule,,,Do not declare an identifier with conflicting linkage classifications,,Declarations,Medium, c,CERT-C,DCL37-C,Yes,Rule,,,Do not declare or define a reserved identifier,,Declarations1,Easy, c,CERT-C,DCL38-C,Yes,Rule,,,Use the correct syntax when declaring a flexible array member,,Declarations,Easy, From af73a7808ec997e55a0f9205acec0aa88401c6b5 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 8 Aug 2022 12:59:09 -0400 Subject: [PATCH 04/24] Declarations1: add rule 21-2 --- ...DoNotDeclareOrDefineAReservedIdentifier.md | 3 +- ...DoNotDeclareOrDefineAReservedIdentifier.ql | 29 ++----- ...otDeclareOrDefineAReservedIdentifier.qlref | 1 - ...DeclareOrDefineAReservedIdentifier.testref | 1 + .../DeclaredAReservedIdentifier.expected} | 0 .../DeclaredAReservedIdentifier.ql | 2 + .../rules/declaredareservedidentifier}/test.c | 0 .../DoNotDeclareAReservedIdentifier.ql | 23 +++++ .../DoNotDeclareAReservedIdentifier.testref | 1 + .../src/codingstandards/cpp/CKeywords.qll | 0 .../cpp/exclusions/c/Declarations1.qll | 18 +++- .../DeclaredAReservedIdentifier.qll | 37 ++++++++ rule_packages/c/Declarations1.json | 87 ++++++++++++------- rules.csv | 2 +- 14 files changed, 146 insertions(+), 58 deletions(-) delete mode 100644 c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.qlref create mode 100644 c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.testref rename c/{cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.expected => common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.expected} (100%) create mode 100644 c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.ql rename c/{cert/test/rules/DCL37-C => common/test/rules/declaredareservedidentifier}/test.c (100%) create mode 100644 c/misra/src/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.ql create mode 100644 c/misra/test/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.testref rename c/common/src/codingstandards/c/Keywords.qll => cpp/common/src/codingstandards/cpp/CKeywords.qll (100%) create mode 100644 cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll diff --git a/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md index ad885f216c..69d7f70211 100644 --- a/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md +++ b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md @@ -4,13 +4,14 @@ This query implements the CERT-C rule DCL37-C: > Do not declare or define a reserved identifier + ## CERT ** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` ** ## Implementation notes -None +This query does not consider identifiers described in the future library directions section of the standard. This query also checks for any reserved identifier as declared regardless of whether its header file is included or not. ## References diff --git a/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.ql b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.ql index 6e931c1ede..99c5a9708b 100644 --- a/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.ql +++ b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.ql @@ -14,27 +14,10 @@ import cpp import codingstandards.c.cert -import codingstandards.cpp.Naming -import codingstandards.c.Keywords +import codingstandards.cpp.rules.declaredareservedidentifier.DeclaredAReservedIdentifier -from Element m, string name -where - not isExcluded(m, Declarations1Package::doNotDeclareOrDefineAReservedIdentifierQuery()) and - ( - m.(Macro).hasName(name) or - m.(Declaration).hasGlobalName(name) - ) and - ( - Naming::Cpp14::hasStandardLibraryMacroName(name) - or - Naming::Cpp14::hasStandardLibraryObjectName(name) - or - Naming::Cpp14::hasStandardLibraryFunctionName(name) - or - name.regexpMatch("_[A-Z_].*") - or - name.regexpMatch("_.*") and m.(Declaration).hasGlobalName(name) - or - Keywords::isKeyword(name) - ) -select m, "Reserved identifier '" + name + "' is declared." +class DoNotDeclareAReservedIdentifierQuery extends DeclaredAReservedIdentifierSharedQuery { + DoNotDeclareAReservedIdentifierQuery() { + this = Declarations1Package::doNotDeclareOrDefineAReservedIdentifierQuery() + } +} diff --git a/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.qlref b/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.qlref deleted file mode 100644 index 40ad8eb138..0000000000 --- a/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.ql \ No newline at end of file diff --git a/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.testref b/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.testref new file mode 100644 index 0000000000..32b1b02bf4 --- /dev/null +++ b/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.testref @@ -0,0 +1 @@ +c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.ql \ No newline at end of file diff --git a/c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.expected b/c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.expected similarity index 100% rename from c/cert/test/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.expected rename to c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.expected diff --git a/c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.ql b/c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.ql new file mode 100644 index 0000000000..c53a7c44b2 --- /dev/null +++ b/c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.ql @@ -0,0 +1,2 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.declaredareservedidentifier.DeclaredAReservedIdentifier diff --git a/c/cert/test/rules/DCL37-C/test.c b/c/common/test/rules/declaredareservedidentifier/test.c similarity index 100% rename from c/cert/test/rules/DCL37-C/test.c rename to c/common/test/rules/declaredareservedidentifier/test.c diff --git a/c/misra/src/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.ql b/c/misra/src/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.ql new file mode 100644 index 0000000000..89140222da --- /dev/null +++ b/c/misra/src/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.ql @@ -0,0 +1,23 @@ +/** + * @id c/misra/do-not-declare-a-reserved-identifier + * @name RULE-21-2: A reserved identifier or reserved macro name shall not be declared + * @description Declaring a reserved identifier can lead to undefined behaviour. + * @kind problem + * @precision very-high + * @problem.severity warning + * @tags external/misra/id/rule-21-2 + * correctness + * maintainability + * readability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.cpp.rules.declaredareservedidentifier.DeclaredAReservedIdentifier + +class DoNotDeclareAReservedIdentifierQuery extends DeclaredAReservedIdentifierSharedQuery { + DoNotDeclareAReservedIdentifierQuery() { + this = Declarations1Package::doNotDeclareAReservedIdentifierQuery() + } +} diff --git a/c/misra/test/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.testref b/c/misra/test/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.testref new file mode 100644 index 0000000000..32b1b02bf4 --- /dev/null +++ b/c/misra/test/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.testref @@ -0,0 +1 @@ +c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.ql \ No newline at end of file diff --git a/c/common/src/codingstandards/c/Keywords.qll b/cpp/common/src/codingstandards/cpp/CKeywords.qll similarity index 100% rename from c/common/src/codingstandards/c/Keywords.qll rename to cpp/common/src/codingstandards/cpp/CKeywords.qll diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll index d2551a7cb9..9cb295a008 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll @@ -5,7 +5,8 @@ import codingstandards.cpp.exclusions.RuleMetadata newtype Declarations1Query = TDeclareIdentifiersBeforeUsingThemQuery() or - TDoNotDeclareOrDefineAReservedIdentifierQuery() + TDoNotDeclareOrDefineAReservedIdentifierQuery() or + TDoNotDeclareAReservedIdentifierQuery() predicate isDeclarations1QueryMetadata(Query query, string queryId, string ruleId) { query = @@ -23,6 +24,14 @@ predicate isDeclarations1QueryMetadata(Query query, string queryId, string ruleI // `@id` for the `doNotDeclareOrDefineAReservedIdentifier` query "c/cert/do-not-declare-or-define-a-reserved-identifier" and ruleId = "DCL37-C" + or + query = + // `Query` instance for the `doNotDeclareAReservedIdentifier` query + Declarations1Package::doNotDeclareAReservedIdentifierQuery() and + queryId = + // `@id` for the `doNotDeclareAReservedIdentifier` query + "c/misra/do-not-declare-a-reserved-identifier" and + ruleId = "RULE-21-2" } module Declarations1Package { @@ -39,4 +48,11 @@ module Declarations1Package { // `Query` type for `doNotDeclareOrDefineAReservedIdentifier` query TQueryC(TDeclarations1PackageQuery(TDoNotDeclareOrDefineAReservedIdentifierQuery())) } + + Query doNotDeclareAReservedIdentifierQuery() { + //autogenerate `Query` type + result = + // `Query` type for `doNotDeclareAReservedIdentifier` query + TQueryC(TDeclarations1PackageQuery(TDoNotDeclareAReservedIdentifierQuery())) + } } diff --git a/cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll b/cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll new file mode 100644 index 0000000000..f1fdf06862 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll @@ -0,0 +1,37 @@ +/** + * Provides a library which includes a `problems` predicate for reporting declarations of reserved identifiers. + */ + +import cpp +import codingstandards.cpp.Customizations +import codingstandards.cpp.Exclusions +import codingstandards.cpp.Naming +import codingstandards.cpp.CKeywords + +abstract class DeclaredAReservedIdentifierSharedQuery extends Query { } + +Query getQuery() { result instanceof DeclaredAReservedIdentifierSharedQuery } + +query predicate problems(Element m, string message) { + not isExcluded(m, getQuery()) and + exists(string name | + ( + m.(Macro).hasName(name) or + m.(Declaration).hasGlobalName(name) + ) and + ( + Naming::Cpp14::hasStandardLibraryMacroName(name) + or + Naming::Cpp14::hasStandardLibraryObjectName(name) + or + Naming::Cpp14::hasStandardLibraryFunctionName(name) + or + name.regexpMatch("_[A-Z_].*") + or + name.regexpMatch("_.*") and m.(Declaration).hasGlobalName(name) + or + Keywords::isKeyword(name) + ) and + message = "Reserved identifier '" + name + "' is declared." + ) +} diff --git a/rule_packages/c/Declarations1.json b/rule_packages/c/Declarations1.json index 2ca9f836bd..5d66329a23 100644 --- a/rule_packages/c/Declarations1.json +++ b/rule_packages/c/Declarations1.json @@ -1,53 +1,78 @@ { "CERT-C": { "DCL31-C": { - "properties": { - "obligation": "rule" + "properties": { + "obligation": "rule" + }, + "queries": [ + { + "description": "Omission of type specifiers may not be supported by some compilers.", + "kind": "problem", + "name": "Declare identifiers before using them", + "precision": "very-high", + "severity": "error", + "short_name": "DeclareIdentifiersBeforeUsingThem", + "tags": [ + "correctness", + "readability" + ], + "implementation_scope": { + "description": "This query does not check for implicit function declarations as this is partially compiler checked.", + "items": [] + } + } + ], + "title": "Declare identifiers before using them" }, - "queries": [ - { - "description": "Omission of type specifiers may not be supported by some compilers.", - "kind": "problem", - "name": "Declare identifiers before using them", - "precision": "very-high", - "severity": "error", - "short_name": "DeclareIdentifiersBeforeUsingThem", - "tags": [ - "correctness", - "readability" - ], - "implementation_scope": { - "description": "This query does not check for implicit function declarations as this is partially compiler checked.", - "items": [] + "DCL37-C": { + "properties": { + "obligation": "rule" + }, + "queries": [ + { + "description": "Declaring a reserved identifier can lead to undefined behaviour.", + "kind": "problem", + "name": "Do not declare or define a reserved identifier", + "precision": "very-high", + "severity": "warning", + "short_name": "DoNotDeclareOrDefineAReservedIdentifier", + "shared_implementation_short_name": "DeclaredAReservedIdentifier", + "tags": [ + "correctness", + "maintainability", + "readability" + ], + "implementation_scope": { + "description": "This query does not consider identifiers described in the future library directions section of the standard. This query also checks for any reserved identifier as declared regardless of whether its header file is included or not.", + "items": [] + } } - } - ], - "title": "Declare identifiers before using them" - }, - "DCL37-C": { + ], + "title": "Do not declare or define a reserved identifier" + } + }, + "MISRA-C-2012": { + "RULE-21-2": { "properties": { - "obligation": "rule" + "obligation": "required" }, "queries": [ { "description": "Declaring a reserved identifier can lead to undefined behaviour.", "kind": "problem", - "name": "Do not declare or define a reserved identifier", + "name": "A reserved identifier or reserved macro name shall not be declared", "precision": "very-high", "severity": "warning", - "short_name": "DoNotDeclareOrDefineAReservedIdentifier", + "short_name": "DoNotDeclareAReservedIdentifier", + "shared_implementation_short_name": "DeclaredAReservedIdentifier", "tags": [ "correctness", "maintainability", "readability" - ], - "implementation_scope": { - "description": "This query does not consider identifiers described in the future library directions section of the standard. This query also checks for any reserved identifier as declared regardless of whether its header file is included or not.", - "items": [] - } + ] } ], - "title": "Do not declare or define a reserved identifier" + "title": "A reserved identifier or reserved macro name shall not be declared" } } } \ No newline at end of file diff --git a/rules.csv b/rules.csv index 8343e34230..90de8edb31 100755 --- a/rules.csv +++ b/rules.csv @@ -744,7 +744,7 @@ c,MISRA-C-2012,RULE-20-12,Yes,Required,,,"A macro parameter used as an operand t c,MISRA-C-2012,RULE-20-13,No,Required,,,A line whose first token is # shall be a valid preprocessing directive,M16-0-8,,,This is verified by the compiler in the cases where the token is not within an ifdef branch that's never taken c,MISRA-C-2012,RULE-20-14,No,Required,,,"All #else, #elif and #endif preprocessor directives shall reside in the same file as the #if, #ifdef or #ifndef directive to which they are related",M16-1-2,,,Compilers already prohibit this case c,MISRA-C-2012,RULE-21-1,Yes,Required,,,#define and #undef shall not be used on a reserved identifier or reserved macro name,,Preprocessor4,Hard, -c,MISRA-C-2012,RULE-21-2,Yes,Required,,,A reserved identifier or reserved macro name shall not be declared,,Declarations,Hard, +c,MISRA-C-2012,RULE-21-2,Yes,Required,,,A reserved identifier or reserved macro name shall not be declared,,Declarations1,Hard, c,MISRA-C-2012,RULE-21-3,Yes,Required,,,The memory allocation and deallocation functions of shall not be used,,Banned,Medium, c,MISRA-C-2012,RULE-21-4,Yes,Required,,,The standard header file shall not be used ,,Banned,Easy, c,MISRA-C-2012,RULE-21-5,Yes,Required,,,The standard header file shall not be used ,,Banned,Easy, From cb339b5a996218d57f96f21f809f33d75793603d Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 8 Aug 2022 13:11:51 -0400 Subject: [PATCH 05/24] Declarations1: fix test format DCL31-C --- c/cert/test/rules/DCL31-C/test.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/c/cert/test/rules/DCL31-C/test.c b/c/cert/test/rules/DCL31-C/test.c index 0b3201bf35..ac901117bd 100644 --- a/c/cert/test/rules/DCL31-C/test.c +++ b/c/cert/test/rules/DCL31-C/test.c @@ -1,12 +1,12 @@ -extern g; //NON_COMPLIANT +extern g; // NON_COMPLIANT -extern int g1; //COMPLIANT +extern int g1; // COMPLIANT -f(void) { //NON_COMPLIANT +f(void) { // NON_COMPLIANT return 1; } -int f1(void) { //COMPLIANT +int f1(void) { // COMPLIANT return 1; } \ No newline at end of file From 0b2ecfc758ab99e586857b474298dea8615405c9 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 8 Aug 2022 15:27:42 -0400 Subject: [PATCH 06/24] Declarations1: add rule 5-4 --- ...MacroIdentifierNotDistinctFromParameter.ql | 22 +++++++++++ .../RULE-5-4/MacroIdentifiersNotDistinct.ql | 27 +++++++++++++ ...dentifierNotDistinctFromParameter.expected | 1 + ...roIdentifierNotDistinctFromParameter.qlref | 1 + .../MacroIdentifiersNotDistinct.expected | 4 ++ .../MacroIdentifiersNotDistinct.qlref | 1 + c/misra/test/rules/RULE-5-4/test.c | 9 +++++ .../cpp/exclusions/c/Declarations1.qll | 34 ++++++++++++++++- rule_packages/c/Declarations1.json | 38 +++++++++++++++++++ rules.csv | 2 +- 10 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql create mode 100644 c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql create mode 100644 c/misra/test/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.expected create mode 100644 c/misra/test/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.qlref create mode 100644 c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected create mode 100644 c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.qlref create mode 100644 c/misra/test/rules/RULE-5-4/test.c diff --git a/c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql b/c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql new file mode 100644 index 0000000000..7e196007a6 --- /dev/null +++ b/c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql @@ -0,0 +1,22 @@ +/** + * @id c/misra/macro-identifier-not-distinct-from-parameter + * @name RULE-5-4: Macro identifiers shall be distinct + * @description Macros with the same name as their parameters are less readable. + * @kind problem + * @precision very-high + * @problem.severity warning + * @tags external/misra/id/rule-5-4 + * maintainability + * readability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.cpp.FunctionLikeMacro + +from FunctionLikeMacro m +where + not isExcluded(m, Declarations1Package::macroIdentifierNotDistinctFromParameterQuery()) and + exists(string p | p = m.(FunctionLikeMacro).getAParameter() and p = m.getName()) +select m, "Macro name matches parameter " + m.getName() + " ." diff --git a/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql new file mode 100644 index 0000000000..0baa9587a8 --- /dev/null +++ b/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql @@ -0,0 +1,27 @@ +/** + * @id c/misra/macro-identifiers-not-distinct + * @name RULE-5-4: Macro identifiers shall be distinct + * @description Declaring multiple macros with the same name leads to undefined behaviour. + * @kind problem + * @precision very-high + * @problem.severity warning + * @tags external/misra/id/rule-5-4 + * correctness + * maintainability + * readability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra + +from Macro m +where + not isExcluded(m, Declarations1Package::macroIdentifiersNotDistinctQuery()) and + exists(Macro m2 | + not m = m2 and + if m.getName().length() >= 64 + then m.getName().substring(0, 62) = m2.getName().substring(0, 62) + else m.getName() = m2.getName() + ) +select m, "Nondistinct macro identifer used " + m.getName() + " ." diff --git a/c/misra/test/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.expected b/c/misra/test/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.expected new file mode 100644 index 0000000000..df55a62ed3 --- /dev/null +++ b/c/misra/test/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.expected @@ -0,0 +1 @@ +| test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | Macro name matches parameter FUNCTION_MACRO . | diff --git a/c/misra/test/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.qlref b/c/misra/test/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.qlref new file mode 100644 index 0000000000..961df59e11 --- /dev/null +++ b/c/misra/test/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.qlref @@ -0,0 +1 @@ +rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected b/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected new file mode 100644 index 0000000000..d4e2f469c5 --- /dev/null +++ b/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected @@ -0,0 +1,4 @@ +| test.c:1:1:1:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA | Nondistinct macro identifer used iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA . | +| test.c:2:1:2:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB | Nondistinct macro identifer used iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB . | +| test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | Nondistinct macro identifer used FUNCTION_MACRO . | +| test.c:8:1:8:31 | #define FUNCTION_MACRO(X) X + 1 | Nondistinct macro identifer used FUNCTION_MACRO . | diff --git a/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.qlref b/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.qlref new file mode 100644 index 0000000000..76762609f3 --- /dev/null +++ b/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.qlref @@ -0,0 +1 @@ +rules/RULE-5-4/MacroIdentifiersNotDistinct.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-5-4/test.c b/c/misra/test/rules/RULE-5-4/test.c new file mode 100644 index 0000000000..3ff498a2e7 --- /dev/null +++ b/c/misra/test/rules/RULE-5-4/test.c @@ -0,0 +1,9 @@ +#define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA // NON_COMPLIANT +#define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB // NON_COMPLIANT + +#define MACRO1 // COMPLIANT +#define MACRO2 // COMPLIANT + +#define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 // NON_COMPLIANT +#define FUNCTION_MACRO(X) X + 1 // NON_COMPLIANT +#define FUNCTION_MACRO2(X) X + 1 // COMPLIANT \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll index 9cb295a008..76c0b43821 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll @@ -6,7 +6,9 @@ import codingstandards.cpp.exclusions.RuleMetadata newtype Declarations1Query = TDeclareIdentifiersBeforeUsingThemQuery() or TDoNotDeclareOrDefineAReservedIdentifierQuery() or - TDoNotDeclareAReservedIdentifierQuery() + TDoNotDeclareAReservedIdentifierQuery() or + TMacroIdentifiersNotDistinctQuery() or + TMacroIdentifierNotDistinctFromParameterQuery() predicate isDeclarations1QueryMetadata(Query query, string queryId, string ruleId) { query = @@ -32,6 +34,22 @@ predicate isDeclarations1QueryMetadata(Query query, string queryId, string ruleI // `@id` for the `doNotDeclareAReservedIdentifier` query "c/misra/do-not-declare-a-reserved-identifier" and ruleId = "RULE-21-2" + or + query = + // `Query` instance for the `macroIdentifiersNotDistinct` query + Declarations1Package::macroIdentifiersNotDistinctQuery() and + queryId = + // `@id` for the `macroIdentifiersNotDistinct` query + "c/misra/macro-identifiers-not-distinct" and + ruleId = "RULE-5-4" + or + query = + // `Query` instance for the `macroIdentifierNotDistinctFromParameter` query + Declarations1Package::macroIdentifierNotDistinctFromParameterQuery() and + queryId = + // `@id` for the `macroIdentifierNotDistinctFromParameter` query + "c/misra/macro-identifier-not-distinct-from-parameter" and + ruleId = "RULE-5-4" } module Declarations1Package { @@ -55,4 +73,18 @@ module Declarations1Package { // `Query` type for `doNotDeclareAReservedIdentifier` query TQueryC(TDeclarations1PackageQuery(TDoNotDeclareAReservedIdentifierQuery())) } + + Query macroIdentifiersNotDistinctQuery() { + //autogenerate `Query` type + result = + // `Query` type for `macroIdentifiersNotDistinct` query + TQueryC(TDeclarations1PackageQuery(TMacroIdentifiersNotDistinctQuery())) + } + + Query macroIdentifierNotDistinctFromParameterQuery() { + //autogenerate `Query` type + result = + // `Query` type for `macroIdentifierNotDistinctFromParameter` query + TQueryC(TDeclarations1PackageQuery(TMacroIdentifierNotDistinctFromParameterQuery())) + } } diff --git a/rule_packages/c/Declarations1.json b/rule_packages/c/Declarations1.json index 5d66329a23..a936598231 100644 --- a/rule_packages/c/Declarations1.json +++ b/rule_packages/c/Declarations1.json @@ -73,6 +73,44 @@ } ], "title": "A reserved identifier or reserved macro name shall not be declared" + }, + "RULE-5-4": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "Declaring multiple macros with the same name leads to undefined behaviour.", + "kind": "problem", + "name": "Macro identifiers shall be distinct", + "precision": "very-high", + "severity": "warning", + "short_name": "MacroIdentifiersNotDistinct", + "tags": [ + "correctness", + "maintainability", + "readability" + ] + , + "implementation_scope": { + "description": "This query checks the first 63 characters of macro identifiers as significant, as per C99. Distinctness of parameters within the same function like macro are checked by compiler and therefore not checked by this rule.", + "items": [] + } + }, + { + "description": "Macros with the same name as their parameters are less readable.", + "kind": "problem", + "name": "Macro identifiers shall be distinct", + "precision": "very-high", + "severity": "warning", + "short_name": "MacroIdentifierNotDistinctFromParameter", + "tags": [ + "maintainability", + "readability" + ] + } + ], + "title": "Macro identifiers shall be distinct" } } } \ No newline at end of file diff --git a/rules.csv b/rules.csv index 90de8edb31..1f0ec31320 100755 --- a/rules.csv +++ b/rules.csv @@ -634,7 +634,7 @@ c,MISRA-C-2012,RULE-4-2,No,Advisory,,,Trigraphs should not be used,A2-5-1,,Impor c,MISRA-C-2012,RULE-5-1,Yes,Required,,,External identifiers shall be distinct,,Declarations,Medium, c,MISRA-C-2012,RULE-5-2,Yes,Required,,,Identifiers declared in the same scope and name space shall be distinct,,Declarations,Medium, c,MISRA-C-2012,RULE-5-3,Yes,Required,,,An identifier declared in an inner scope shall not hide an identifier declared in an outer scope,A2-10-1,Declarations,Import, -c,MISRA-C-2012,RULE-5-4,Yes,Required,,,Macro identifiers shall be distinct,,Declarations,Easy, +c,MISRA-C-2012,RULE-5-4,Yes,Required,,,Macro identifiers shall be distinct,,Declarations1,Easy, c,MISRA-C-2012,RULE-5-5,Yes,Required,,,Identifiers shall be distinct from macro names,,Declarations,Easy, c,MISRA-C-2012,RULE-5-6,Yes,Required,,,A typedef name shall be a unique identifier,,Declarations,Easy, c,MISRA-C-2012,RULE-5-7,Yes,Required,,,A tag name shall be a unique identifier,,Declarations,Easy, From 24547a7a6d254861ebef87d53d2585f773028f05 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Tue, 9 Aug 2022 10:21:08 -0400 Subject: [PATCH 07/24] Declarations1: fix rule 20-4 after lib rename --- .../src/rules/RULE-20-4/MacroDefinedWithTheSameNameAsKeyword.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/misra/src/rules/RULE-20-4/MacroDefinedWithTheSameNameAsKeyword.ql b/c/misra/src/rules/RULE-20-4/MacroDefinedWithTheSameNameAsKeyword.ql index 5ec14f4df1..6b9ae71120 100644 --- a/c/misra/src/rules/RULE-20-4/MacroDefinedWithTheSameNameAsKeyword.ql +++ b/c/misra/src/rules/RULE-20-4/MacroDefinedWithTheSameNameAsKeyword.ql @@ -16,7 +16,7 @@ import cpp import codingstandards.c.misra -import codingstandards.c.Keywords +import codingstandards.cpp.CKeywords from Macro m, string name where From a1380bb2539b2d0d78848323eb9775fa346980c9 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Tue, 9 Aug 2022 14:19:51 -0400 Subject: [PATCH 08/24] Declarations1: add rule 5-1 --- .../ExternalIdentifiersNotDistinct.ql | 36 +++++++++++ .../ExternalIdentifiersNotDistinct.expected | 2 + .../ExternalIdentifiersNotDistinct.qlref | 1 + c/misra/test/rules/RULE-5-1/test.c | 5 ++ .../cpp/exclusions/c/Declarations1.qll | 16 +++++ rule_packages/c/Declarations1.json | 60 +++++++++++++------ rules.csv | 2 +- 7 files changed, 103 insertions(+), 19 deletions(-) create mode 100644 c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql create mode 100644 c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected create mode 100644 c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.qlref create mode 100644 c/misra/test/rules/RULE-5-1/test.c diff --git a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql new file mode 100644 index 0000000000..8bdcaba02d --- /dev/null +++ b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql @@ -0,0 +1,36 @@ +/** + * @id c/misra/external-identifiers-not-distinct + * @name RULE-5-1: External identifiers shall be distinct + * @description Using nondistinct external identifiers results in undefined behaviour. + * @kind problem + * @precision very-high + * @problem.severity warning + * @tags external/misra/id/rule-5-1 + * correctness + * maintainability + * readability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.cpp.Linkage + +class ExternalIdentifiers extends Declaration { + ExternalIdentifiers() { hasExternalLinkage(this) } +} + +class ExternalIdentifiersLong extends ExternalIdentifiers { + ExternalIdentifiersLong() { this.getName().length() >= 32 } +} + +predicate notSame(ExternalIdentifiers d, ExternalIdentifiers d2) { not d = d2 } + +from ExternalIdentifiers d, ExternalIdentifiers d2 +where + not isExcluded(d, Declarations1Package::externalIdentifiersNotDistinctQuery()) and + notSame(d, d2) and + if d instanceof ExternalIdentifiersLong and d2 instanceof ExternalIdentifiersLong + then d.getName().substring(0, 30) = d2.getName().substring(0, 30) + else d.getName() = d2.getName() +select d, "External identifer is nondistinct " + d.getName() + " compared to $@.", d2, d.getName() diff --git a/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected b/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected new file mode 100644 index 0000000000..fa658750f0 --- /dev/null +++ b/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected @@ -0,0 +1,2 @@ +| test.c:1:5:1:36 | iltiqzxgfqsgigwfuyntzghvzltueeeA | External identifer is nondistinct iltiqzxgfqsgigwfuyntzghvzltueeeA compared to $@. | test.c:2:5:2:36 | iltiqzxgfqsgigwfuyntzghvzltueeeB | iltiqzxgfqsgigwfuyntzghvzltueeeA | +| test.c:2:5:2:36 | iltiqzxgfqsgigwfuyntzghvzltueeeB | External identifer is nondistinct iltiqzxgfqsgigwfuyntzghvzltueeeB compared to $@. | test.c:1:5:1:36 | iltiqzxgfqsgigwfuyntzghvzltueeeA | iltiqzxgfqsgigwfuyntzghvzltueeeB | diff --git a/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.qlref b/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.qlref new file mode 100644 index 0000000000..965e5c3298 --- /dev/null +++ b/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.qlref @@ -0,0 +1 @@ +rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-5-1/test.c b/c/misra/test/rules/RULE-5-1/test.c new file mode 100644 index 0000000000..623540657f --- /dev/null +++ b/c/misra/test/rules/RULE-5-1/test.c @@ -0,0 +1,5 @@ +int iltiqzxgfqsgigwfuyntzghvzltueeeA; // NON_COMPLIANT +int iltiqzxgfqsgigwfuyntzghvzltueeeB; // NON_COMPLIANT + +int var1; // COMPLIANT +int var2; // COMPLIANT \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll index 76c0b43821..c52cd567c8 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations1.qll @@ -7,6 +7,7 @@ newtype Declarations1Query = TDeclareIdentifiersBeforeUsingThemQuery() or TDoNotDeclareOrDefineAReservedIdentifierQuery() or TDoNotDeclareAReservedIdentifierQuery() or + TExternalIdentifiersNotDistinctQuery() or TMacroIdentifiersNotDistinctQuery() or TMacroIdentifierNotDistinctFromParameterQuery() @@ -35,6 +36,14 @@ predicate isDeclarations1QueryMetadata(Query query, string queryId, string ruleI "c/misra/do-not-declare-a-reserved-identifier" and ruleId = "RULE-21-2" or + query = + // `Query` instance for the `externalIdentifiersNotDistinct` query + Declarations1Package::externalIdentifiersNotDistinctQuery() and + queryId = + // `@id` for the `externalIdentifiersNotDistinct` query + "c/misra/external-identifiers-not-distinct" and + ruleId = "RULE-5-1" + or query = // `Query` instance for the `macroIdentifiersNotDistinct` query Declarations1Package::macroIdentifiersNotDistinctQuery() and @@ -74,6 +83,13 @@ module Declarations1Package { TQueryC(TDeclarations1PackageQuery(TDoNotDeclareAReservedIdentifierQuery())) } + Query externalIdentifiersNotDistinctQuery() { + //autogenerate `Query` type + result = + // `Query` type for `externalIdentifiersNotDistinct` query + TQueryC(TDeclarations1PackageQuery(TExternalIdentifiersNotDistinctQuery())) + } + Query macroIdentifiersNotDistinctQuery() { //autogenerate `Query` type result = diff --git a/rule_packages/c/Declarations1.json b/rule_packages/c/Declarations1.json index a936598231..1df0d038d6 100644 --- a/rule_packages/c/Declarations1.json +++ b/rule_packages/c/Declarations1.json @@ -74,43 +74,67 @@ ], "title": "A reserved identifier or reserved macro name shall not be declared" }, - "RULE-5-4": { + "RULE-5-1": { "properties": { "obligation": "required" }, "queries": [ { - "description": "Declaring multiple macros with the same name leads to undefined behaviour.", + "description": "Using nondistinct external identifiers results in undefined behaviour.", "kind": "problem", - "name": "Macro identifiers shall be distinct", + "name": "External identifiers shall be distinct", "precision": "very-high", "severity": "warning", - "short_name": "MacroIdentifiersNotDistinct", + "short_name": "ExternalIdentifiersNotDistinct", "tags": [ "correctness", "maintainability", "readability" - ] - , - "implementation_scope": { - "description": "This query checks the first 63 characters of macro identifiers as significant, as per C99. Distinctness of parameters within the same function like macro are checked by compiler and therefore not checked by this rule.", - "items": [] - } + ], + "implementation_scope": { + "description": "This query checks the first 31 characters of identifiers as significant, as per C99. This query does not consider universal or extended source characters.", + "items": [] + } + } + ], + "title": "External identifiers shall be distinct" + }, + "RULE-5-4": { + "properties": { + "obligation": "required" }, - { - "description": "Macros with the same name as their parameters are less readable.", + "queries": [ + { + "description": "Declaring multiple macros with the same name leads to undefined behaviour.", "kind": "problem", "name": "Macro identifiers shall be distinct", "precision": "very-high", "severity": "warning", - "short_name": "MacroIdentifierNotDistinctFromParameter", + "short_name": "MacroIdentifiersNotDistinct", "tags": [ + "correctness", "maintainability", "readability" - ] - } - ], - "title": "Macro identifiers shall be distinct" - } + ], + "implementation_scope": { + "description": "This query checks the first 63 characters of macro identifiers as significant, as per C99. Distinctness of parameters within the same function like macro are checked by compiler and therefore not checked by this rule.", + "items": [] + } + }, + { + "description": "Macros with the same name as their parameters are less readable.", + "kind": "problem", + "name": "Macro identifiers shall be distinct", + "precision": "very-high", + "severity": "warning", + "short_name": "MacroIdentifierNotDistinctFromParameter", + "tags": [ + "maintainability", + "readability" + ] + } + ], + "title": "Macro identifiers shall be distinct" + } } } \ No newline at end of file diff --git a/rules.csv b/rules.csv index 1f0ec31320..0741a5143f 100755 --- a/rules.csv +++ b/rules.csv @@ -631,7 +631,7 @@ c,MISRA-C-2012,RULE-3-1,Yes,Required,,,The character sequences /* and // shall n c,MISRA-C-2012,RULE-3-2,Yes,Required,,,Line-splicing shall not be used in // comments,,Syntax,Easy, c,MISRA-C-2012,RULE-4-1,Yes,Required,,,Octal and hexadecimal escape sequences shall be terminated,A2-13-1 M2-13-2,Syntax,Medium, c,MISRA-C-2012,RULE-4-2,No,Advisory,,,Trigraphs should not be used,A2-5-1,,Import, -c,MISRA-C-2012,RULE-5-1,Yes,Required,,,External identifiers shall be distinct,,Declarations,Medium, +c,MISRA-C-2012,RULE-5-1,Yes,Required,,,External identifiers shall be distinct,,Declarations1,Medium, c,MISRA-C-2012,RULE-5-2,Yes,Required,,,Identifiers declared in the same scope and name space shall be distinct,,Declarations,Medium, c,MISRA-C-2012,RULE-5-3,Yes,Required,,,An identifier declared in an inner scope shall not hide an identifier declared in an outer scope,A2-10-1,Declarations,Import, c,MISRA-C-2012,RULE-5-4,Yes,Required,,,Macro identifiers shall be distinct,,Declarations1,Easy, From 4e118630b7c5b720c3be12e3cbe4defeb36a3c23 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Tue, 9 Aug 2022 16:28:57 -0400 Subject: [PATCH 09/24] Declarations1: improve alert message rules 5-1 and 5-4 --- .../rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql | 5 ++++- .../rules/RULE-5-4/MacroIdentifiersNotDistinct.ql | 12 +++++++----- .../RULE-5-4/MacroIdentifiersNotDistinct.expected | 6 ++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql index 8bdcaba02d..ffa572c234 100644 --- a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql +++ b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql @@ -24,7 +24,10 @@ class ExternalIdentifiersLong extends ExternalIdentifiers { ExternalIdentifiersLong() { this.getName().length() >= 32 } } -predicate notSame(ExternalIdentifiers d, ExternalIdentifiers d2) { not d = d2 } +predicate notSame(ExternalIdentifiers d, ExternalIdentifiers d2) { + not d = d2 and + d.getLocation().getStartLine() >= d2.getLocation().getStartLine() +} from ExternalIdentifiers d, ExternalIdentifiers d2 where diff --git a/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql index 0baa9587a8..4040439860 100644 --- a/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql +++ b/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql @@ -15,13 +15,15 @@ import cpp import codingstandards.c.misra -from Macro m +from Macro m, Macro m2 where not isExcluded(m, Declarations1Package::macroIdentifiersNotDistinctQuery()) and - exists(Macro m2 | - not m = m2 and + not m = m2 and + ( if m.getName().length() >= 64 then m.getName().substring(0, 62) = m2.getName().substring(0, 62) else m.getName() = m2.getName() - ) -select m, "Nondistinct macro identifer used " + m.getName() + " ." + ) and + //reduce double report since both macros are in alert, arbitrary ordering + m.getLocation().getStartLine() >= m2.getLocation().getStartLine() +select m, "Nondistinct macro identifer used " + m.getName() + " compared to $@.", m2, m2.getName() diff --git a/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected b/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected index d4e2f469c5..41e4908d2f 100644 --- a/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected +++ b/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected @@ -1,4 +1,2 @@ -| test.c:1:1:1:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA | Nondistinct macro identifer used iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA . | -| test.c:2:1:2:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB | Nondistinct macro identifer used iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB . | -| test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | Nondistinct macro identifer used FUNCTION_MACRO . | -| test.c:8:1:8:31 | #define FUNCTION_MACRO(X) X + 1 | Nondistinct macro identifer used FUNCTION_MACRO . | +| test.c:2:1:2:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB | Nondistinct macro identifer used iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB compared to $@. | test.c:1:1:1:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA | iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA | +| test.c:8:1:8:31 | #define FUNCTION_MACRO(X) X + 1 | Nondistinct macro identifer used FUNCTION_MACRO compared to $@. | test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | FUNCTION_MACRO | From 4b09e606b206243b95f00a923fd553a2f6589f27 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Wed, 10 Aug 2022 09:19:16 -0400 Subject: [PATCH 10/24] Declarations1: add cert help files --- .../DeclareIdentifiersBeforeUsingThem.md | 147 +++++++++- ...DoNotDeclareOrDefineAReservedIdentifier.md | 273 +++++++++++++++++- 2 files changed, 416 insertions(+), 4 deletions(-) diff --git a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md index 68103aa881..594e87c4fc 100644 --- a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md +++ b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md @@ -5,9 +5,152 @@ This query implements the CERT-C rule DCL31-C: > Declare identifiers before using them -## CERT -** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` ** +## Description + +The C11 Standard requires type specifiers and forbids implicit function declarations. The C90 Standard allows implicit typing of variables and functions. Consequently, some existing legacy code uses implicit typing. Some C compilers still support legacy code by allowing implicit typing, but it should not be used for new code. Such an [implementation](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-implementation) may choose to assume an implicit declaration and continue translation to support existing programs that used this feature. + +## Noncompliant Code Example (Implicit int) + +C no longer allows the absence of type specifiers in a declaration. The C Standard, 6.7.2 \[ [ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011) \], states + +> At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each `struct` declaration and type name. + + +This noncompliant code example omits the type specifier: + +```cpp +extern foo; + +``` +Some C [implementations](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-implementation) do not issue a diagnostic for the violation of this constraint. These nonconforming C translators continue to treat such declarations as implying the type `int`. + +## Compliant Solution (Implicit int) + +This compliant solution explicitly includes a type specifier: + +```cpp +extern int foo; + +``` + +## Noncompliant Code Example (Implicit Function Declaration) + +Implicit declaration of functions is not allowed; every function must be explicitly declared before it can be called. In C90, if a function is called without an explicit prototype, the compiler provides an implicit declaration. + +The C90 Standard \[[ISO/IEC 9899:1990](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-1990)\] includes this requirement: + +> If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration `extern int identifier();` appeared. + + +If a function declaration is not visible at the point at which a call to the function is made, C90-compliant platforms assume an implicit declaration of `extern int identifier();`. + +This declaration implies that the function may take any number and type of arguments and return an `int`. However, to conform to the current C Standard, programmers must explicitly prototype every function before invoking it. An implementation that conforms to the C Standard may or may not perform implicit function declarations, but C does require a conforming implementation to issue a diagnostic if it encounters an undeclared function being used. + +In this noncompliant code example, if `malloc()` is not declared, either explicitly or by including `stdlib.h`, a compiler that conforms only to C90 may implicitly declare `malloc()` as `int malloc()`. If the platform's size of `int` is 32 bits, but the size of pointers is 64 bits, the resulting pointer would likely be truncated as a result of the implicit declaration of `malloc()`, returning a 32-bit integer. + +```cpp +#include +/* #include is missing */ + +int main(void) { + for (size_t i = 0; i < 100; ++i) { + /* int malloc() assumed */ + char *ptr = (char *)malloc(0x10000000); + *ptr = 'a'; + } + return 0; +} +``` +**Implementation Details** + +When compiled with Microsoft Visual Studio 2013 for a 64-bit platform, this noncompliant code example will eventually cause an access violation when dereferencing `ptr` in the loop. + +## Compliant Solution (Implicit Function Declaration) + +This compliant solution declares `malloc()` by including the appropriate header file: + +```cpp +#include + +int main(void) { + for (size_t i = 0; i < 100; ++i) { + char *ptr = (char *)malloc(0x10000000); + *ptr = 'a'; + } + return 0; +} +``` +For more information on function declarations, see [DCL07-C. Include the appropriate type information in function declarators](https://wiki.sei.cmu.edu/confluence/display/c/DCL07-C.+Include+the+appropriate+type+information+in+function+declarators). + +## Noncompliant Code Example (Implicit Return Type) + +Do not declare a function with an implicit return type. For example, if a function returns a meaningful integer value, declare it as returning `int`. If it returns no meaningful value, declare it as returning `void`. + +```cpp +#include +#include + +foo(void) { + return UINT_MAX; +} + +int main(void) { + long long int c = foo(); + printf("%lld\n", c); + return 0; +} + +``` +Because the compiler assumes that `foo()` returns a value of type `int` for this noncompliant code example, `UINT_MAX` is incorrectly converted to `−1`. + +## Compliant Solution (Implicit Return Type) + +This compliant solution explicitly defines the return type of `foo()` as `unsigned int`. As a result, the function correctly returns ` `UINT_MAX` `. + +```cpp +#include +#include + +unsigned int foo(void) { + return UINT_MAX; +} + +int main(void) { + long long int c = foo(); + printf("%lld\n", c); + return 0; +} + +``` + +## Risk Assessment + +Because implicit declarations lead to less stringent type checking, they can introduce [unexpected](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-unexpectedbehavior) and erroneous behavior. Occurrences of an omitted type specifier in existing code are rare, and the consequences are generally minor, perhaps resulting in [abnormal program termination](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-abnormaltermination). + +
Rule Severity Likelihood Remediation Cost Priority Level
DCL31-C Low Unlikely Low P3 L3
+ + +## Automated Detection + +
Tool Version Checker Description
Astrée 22.04 type-specifier function-return-type implicit-function-declaration undeclared-parameter Fully checked
Axivion Bauhaus Suite 7.2.0 CertC-DCL31 Fully implemented
Clang 3.9 -Wimplicit-int
Compass/ROSE
Coverity 2017.07 MISRA C 2012 Rule 8.1 Implemented
ECLAIR 1.2 CC2.DCL31 Fully implemented
GCC 4.3.5 Can detect violations of this rule when the -Wimplicit and -Wreturn-type flags are used
Helix QAC 2022.2 C0434, C2050, C2051, C3335
Klocwork 2022.2 CWARN.IMPLICITINT MISRA.DECL.NO_TYPE MISRA.FUNC.NOPROT.CALL RETVOID.IMPLICIT
LDRA tool suite 9.7.1 24 D, 41 D, 20 S, 326 S, 496 S Fully implemented
Parasoft C/C++test 2022.1 CERT_C-DCL31-a All functions shall be declared before use
PC-lint Plus 1.4 601, 718, 746, 808 Fully supported
Polyspace Bug Finder R2022a CERT C: Rule DCL31-C Checks for: Types not explicitly specifiedypes not explicitly specified, implicit function declarationmplicit function declaration. Rule fully covered.
PRQA QA-C 9.7 0434 (C)205020513335 Fully implemented
PVS-Studio 7.20 V1031
SonarQube C/C++ Plugin 3.11 S819, S820 Partially implemented; implicit return type not covered.
RuleChecker 22.04 type-specifier function-return-type implicit-function-declaration undeclared-parameter Fully checked
TrustInSoft Analyzer 1.38 type specifier missing Partially verified (exhaustively detects undefined behavior).
+ + +## Related Vulnerabilities + +Search for [vulnerabilities](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-vulnerability) resulting from the violation of this rule on the [CERT website](https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+DCL31-C). + +## Related Guidelines + +[Key here](https://wiki.sei.cmu.edu/confluence/display/c/How+this+Coding+Standard+is+Organized#HowthisCodingStandardisOrganized-RelatedGuidelines) (explains table format and definitions) + +
Taxonomy Taxonomy item Relationship
CERT C Secure Coding Standard DCL07-C. Include the appropriate type information in function declarators Prior to 2018-01-12: CERT: Unspecified Relationship
ISO/IEC TR 24772:2013 Subprogram Signature Mismatch \[OTR\] Prior to 2018-01-12: CERT: Unspecified Relationship
MISRA C:2012 Rule 8.1 (required) Prior to 2018-01-12: CERT: Unspecified Relationship
+ + +## Bibliography + +
\[ ISO/IEC 9899:1990 \]
\[ ISO/IEC 9899:2011 \] Subclause 6.7.2, "Type Specifiers"
\[ Jones 2008 \]
+ ## Implementation notes diff --git a/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md index 69d7f70211..04b29f92fd 100644 --- a/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md +++ b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md @@ -5,9 +5,278 @@ This query implements the CERT-C rule DCL37-C: > Do not declare or define a reserved identifier -## CERT -** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` ** +## Description + +According to the C Standard, 7.1.3 \[[ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011)\], + +> All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use. + + +All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces. + +Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included, unless explicitly stated otherwise. + +All identifiers with external linkage (including future library directions) and `errno` are always reserved for use as identifiers with external linkage. + +Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included. + +Additionally, subclause 7.31 defines many other reserved identifiers for future library directions. + +No other identifiers are reserved. (The POSIX standard extends the set of identifiers reserved by the C Standard to include an open-ended set of its own. See *Portable Operating System Interface \[POSIX®\], Base Specifications, Issue 7*, [Section 2.2](http://www.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_02), "The Compilation Environment" \[[IEEE Std 1003.1-2013](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-IEEEStd1003.1-2013)\].) The behavior of a program that declares or defines an identifier in a context in which it is reserved or that defines a reserved identifier as a macro name is undefined. (See [undefined behavior 106](https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-ub_106).) + +## Noncompliant Code Example (Include Guard) + +A common, but noncompliant, practice is to choose a reserved name for a macro used in a preprocessor conditional guarding against multiple inclusions of a header file. (See also [PRE06-C. Enclose header files in an include guard](https://wiki.sei.cmu.edu/confluence/display/c/PRE06-C.+Enclose+header+files+in+an+include+guard).) The name may clash with reserved names defined by the implementation of the C standard library in its headers or with reserved names implicitly predefined by the compiler even when no C standard library header is included. + +```cpp +#ifndef _MY_HEADER_H_ +#define _MY_HEADER_H_ + +/* Contents of */ + +#endif /* _MY_HEADER_H_ */ + +``` + +## Compliant Solution (Include Guard) + +This compliant solution avoids using leading underscores in the macro name of the include guard: + +```cpp +#ifndef MY_HEADER_H +#define MY_HEADER_H + +/* Contents of */ + +#endif /* MY_HEADER_H */ + +``` + +## Noncompliant Code Example (File Scope Objects) + +In this noncompliant code example, the names of the file scope objects `_max_limit` and `_limit` both begin with an underscore. Because `_max_limit` is static, this declaration might seem to be impervious to clashes with names defined by the implementation. However, because the header `` is included to define `size_t`, a potential for a name clash exists. (Note, however, that a [conforming](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-conformingprogram) compiler may implicitly declare reserved names regardless of whether any C standard library header is explicitly included.) + +In addition, because `_limit` has external linkage, it may clash with a symbol of the same name defined in the language runtime library even if such a symbol is not declared in any header. Consequently, it is not safe to start the name of any file scope identifier with an underscore even if its linkage limits its visibility to a single translation unit. + +```cpp +#include + +static const size_t _max_limit = 1024; +size_t _limit = 100; + +unsigned int getValue(unsigned int count) { + return count < _limit ? count : _limit; +} + +``` + +## Compliant Solution (File Scope Objects) + +In this compliant solution, names of file scope objects do not begin with an underscore: + +```cpp +#include + +static const size_t max_limit = 1024; +size_t limit = 100; + +unsigned int getValue(unsigned int count) { + return count < limit ? count : limit; +} + +``` + +## Noncompliant Code Example (Reserved Macros) + +In this noncompliant code example, because the C standard library header `` is specified to include ``, the name `SIZE_MAX` conflicts with a standard macro of the same name, which is used to denote the upper limit of `size_t`. In addition, although the name `INTFAST16_LIMIT_MAX` is not defined by the C standard library, it is a reserved identifier because it begins with the `INT` prefix and ends with the `_MAX` suffix. (See the C Standard, 7.31.10.) + +```cpp +#include +#include + +static const int_fast16_t INTFAST16_LIMIT_MAX = 12000; + +void print_fast16(int_fast16_t val) { + enum { SIZE_MAX = 80 }; + char buf[SIZE_MAX]; + if (INTFAST16_LIMIT_MAX < val) { + sprintf(buf, "The value is too large"); + } else { + snprintf(buf, SIZE_MAX, "The value is %" PRIdFAST16, val); + } +} + +``` + +## Compliant Solution (Reserved Macros) + +This compliant solution avoids redefining reserved names or using reserved prefixes and suffixes: + +```cpp +#include +#include + +static const int_fast16_t MY_INTFAST16_UPPER_LIMIT = 12000; + +void print_fast16(int_fast16_t val) { + enum { BUFSIZE = 80 }; + char buf[BUFSIZE]; + if (MY_INTFAST16_UPPER_LIMIT < val) { + sprintf(buf, "The value is too large"); + } else { + snprintf(buf, BUFSIZE, "The value is %" PRIdFAST16, val); + } +} + +``` + +## Noncompliant Code Example (Identifiers with External Linkage) + +This noncompliant example provides definitions for the C standard library functions `malloc()` and `free()`. Although this practice is permitted by many traditional implementations of UNIX (for example, the [Dmalloc ](http://dmalloc.com/) library), it is [undefined behavior](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior) according to the C Standard. Even on systems that allow replacing `malloc()`, doing so without also replacing `aligned_alloc()`, `calloc()`, and `realloc()` is likely to cause problems. + +```cpp +#include + +void *malloc(size_t nbytes) { + void *ptr; + /* Allocate storage from own pool and set ptr */ + return ptr; +} + +void free(void *ptr) { + /* Return storage to own pool */ +} + +``` + +## Compliant Solution (Identifiers with External Linkage) + +The compliant, portable solution avoids redefining any C standard library identifiers with external linkage. In addition, it provides definitions for all memory allocation functions: + +```cpp +#include + +void *my_malloc(size_t nbytes) { + void *ptr; + /* Allocate storage from own pool and set ptr */ + return ptr; +} + +void *my_aligned_alloc(size_t alignment, size_t size) { + void *ptr; + /* Allocate storage from own pool, align properly, set ptr */ + return ptr; +} + +void *my_calloc(size_t nelems, size_t elsize) { + void *ptr; + /* Allocate storage from own pool, zero memory, and set ptr */ + return ptr; +} + +void *my_realloc(void *ptr, size_t nbytes) { + /* Reallocate storage from own pool and set ptr */ + return ptr; +} + +void my_free(void *ptr) { + /* Return storage to own pool */ +} + +``` + +## Noncompliant Code Example (errno) + +In addition to symbols defined as functions in each C standard library header, identifiers with external linkage include `errno` and `math_errhandling`. According to the C Standard, 7.5, paragraph 2 \[[ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011)\], the behavior of a program is [undefined](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior) when + +> A macro definition of `errno` is suppressed in order to access an actual object, or the program defines an identifier with the name `errno`. + + +See [undefined behavior 114](https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-ub_114). + +The `errno` identifier expands to a modifiable [lvalue](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-lvalue) that has type `int` but is not necessarily the identifier of an object. It might expand to a modifiable lvalue resulting from a function call, such as `*errno()`. It is unspecified whether `errno` is a macro or an identifier declared with external linkage. If a macro definition is suppressed to access an actual object, or if a program defines an identifier with the name `errno`, the behavior is [undefined](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior). + +Legacy code is apt to include an incorrect declaration, such as the following: + +```cpp +extern int errno; + +``` + +## Compliant Solution (errno) + +The correct way to declare `errno` is to include the header ``: + +```cpp +#include + +``` +[Implementations](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-implementation) [conforming](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-conformingprogram) to C are required to declare `errno` in ``, although some historic implementations failed to do so. + +## Exceptions + +**DCL37-C-EX1:** Provided that a library function can be declared without reference to any type defined in a header, it is permissible to declare that function without including its header provided that declaration is compatible with the standard declaration. + +```cpp +/* Not including stdlib.h */ +void free(void *); + +void func(void *ptr) { + free(ptr); +} +``` +Such code is compliant because the declaration matches what `stdlib.h` would provide and does not redefine the reserved identifier. However, it would not be acceptable to provide a definition for the `free()` function in this example. + +**DCL37-C-EX2:** For compatibility with other compiler vendors or language standard modes, it is acceptable to create a macro identifier that is the same as a reserved identifier so long as the behavior is idempotent, as in this example: + +```cpp +/* Sometimes generated by configuration tools such as autoconf */ +#define const const + +/* Allowed compilers with semantically equivalent extension behavior */ +#define inline __inline +``` +**DCL37-C-EX3:** As a compiler vendor or standard library developer, it is acceptable to use identifiers reserved for your implementation. Reserved identifiers may be defined by the compiler, in standard library headers or headers included by a standard library header, as in this example declaration from the glibc standard C library implementation: + +```cpp +/* + The following declarations of reserved identifiers exist in the glibc implementation of + . The original source code may be found at: + https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=include/stdio.h;hb=HEAD +*/ + +# define __need_size_t +# include +/* Generate a unique file name (and possibly open it). */ +extern int __path_search (char *__tmpl, size_t __tmpl_len, + const char *__dir, const char *__pfx, + int __try_tempdir); +``` + +## Risk Assessment + +Using reserved identifiers can lead to incorrect program operation. + +
Rule Severity Likelihood Remediation Cost Priority Level
DCL37-C Low Unlikely Low P3 L3
+ + +## Automated Detection + +
Tool Version Checker Description
Astrée 22.04 future-library-use language-override language-override-c99 reserved-declaration reserved-declaration-c99 reserved-identifier Partially checked
Axivion Bauhaus Suite 7.2.0 CertC-DCL37 Fully implemented. Reserved identifiers, as in DCL37-C-EX3 , are configurable.
CodeSonar 7.0p0 LANG.STRUCT.DECL.RESERVED Declaration of reserved name
Compass/ROSE
Coverity 2017.07 MISRA C 2004 Rule 20.1 MISRA C 2004 Rule 20.2 MISRA C 2012 Rule 21.1 MISRA C 2012 Rule 21.2 Implemented
ECLAIR 1.2 CC2.DCL37 Fully implemented
Helix QAC 2022.2 C0602, C0603, C4600, C4601, C4602, C4603, C4604, C4605, C4606, C4607, C4608, C4620, C4621, C4622, C4623, C4624, C4640, C4641, C4642, C4643, C4644, C4645
Klocwork 2022.2 MISRA.DEFINE.WRONGNAME.UNDERSCORE MISRA.STDLIB.WRONGNAME.UNDERSCORE MISRA.STDLIB.WRONGNAME
LDRA tool suite 9.7.1 86 S, 218 S, 219 S, 580 S, 626 S Fully Implemented
Parasoft C/C++test 2022.1 CERT_C-DCL37-a Do not \#define or \#undef identifiers with names which start with underscore
PC-lint Plus 1.4 978, 9071, 9093 Partially supported
Polyspace Bug Finder R2022a CERT C: Rule DCL37-C Checks for: Defining and undefining reserved identifiers or macrosefining and undefining reserved identifiers or macros, declaring a reserved identifier or macro nameeclaring a reserved identifier or macro name. Rule partially covered
PRQA QA-C 9.7 0602, 0603, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, 4620, 4621, 4622, 4623, 4624, 4640, 4641, 4642, 4643, 4644, 4645
PVS-Studio 7.19 V677
SonarQube C/C++ Plugin 3.11 S978
RuleChecker 22.04 future-library-use language-override language-override-c99 reserved-declaration reserved-declaration-c99 reserved-identifier Partially checked
+ + +## Related Guidelines + +[Key here](https://wiki.sei.cmu.edu/confluence/display/c/How+this+Coding+Standard+is+Organized#HowthisCodingStandardisOrganized-RelatedGuidelines) (explains table format and definitions) + +
Taxonomy Taxonomy item Relationship
CERT C Secure Coding Standard PRE00-C. Prefer inline or static functions to function-like macros Prior to 2018-01-12: CERT: Unspecified Relationship
CERT C Secure Coding Standard PRE06-C. Enclose header files in an include guard Prior to 2018-01-12: CERT: Unspecified Relationship
CERT C Secure Coding Standard PRE31-C. Avoid side effects in arguments to unsafe macros Prior to 2018-01-12: CERT: Unspecified Relationship
CERT C DCL51-CPP. Do not declare or define a reserved identifier Prior to 2018-01-12: CERT: Unspecified Relationship
ISO/IEC TS 17961 Using identifiers that are reserved for the implementation \[resident\] Prior to 2018-01-12: CERT: Unspecified Relationship
MISRA C:2012 Rule 21.1 (required) Prior to 2018-01-12: CERT: Unspecified Relationship
MISRA C:2012 Rule 21.2 (required) Prior to 2018-01-12: CERT: Unspecified Relationship
+ + +## Bibliography + +
\[ IEEE Std 1003.1-2013 \] Section 2.2, "The Compilation Environment"
\[ ISO/IEC 9899:2011 \] 7.1.3, "Reserved Identifiers" 7.31.10, "Integer Types <stdint.h> "
+ ## Implementation notes From ac74fc0a64faf6e8d454dd69d3265d167d84c55d Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Wed, 10 Aug 2022 09:46:36 -0400 Subject: [PATCH 11/24] Declarations1: fix cert help files --- c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md | 1 - .../src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md | 1 - 2 files changed, 2 deletions(-) diff --git a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md index 594e87c4fc..677e3fcb03 100644 --- a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md +++ b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md @@ -5,7 +5,6 @@ This query implements the CERT-C rule DCL31-C: > Declare identifiers before using them - ## Description The C11 Standard requires type specifiers and forbids implicit function declarations. The C90 Standard allows implicit typing of variables and functions. Consequently, some existing legacy code uses implicit typing. Some C compilers still support legacy code by allowing implicit typing, but it should not be used for new code. Such an [implementation](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-implementation) may choose to assume an implicit declaration and continue translation to support existing programs that used this feature. diff --git a/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md index 04b29f92fd..bdf9294d23 100644 --- a/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md +++ b/c/cert/src/rules/DCL37-C/DoNotDeclareOrDefineAReservedIdentifier.md @@ -5,7 +5,6 @@ This query implements the CERT-C rule DCL37-C: > Do not declare or define a reserved identifier - ## Description According to the C Standard, 7.1.3 \[[ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011)\], From 5b025badbabf03f3eb9a2179b4c7727e6d23b9de Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Wed, 10 Aug 2022 10:50:18 -0400 Subject: [PATCH 12/24] Declarations1: fix expected rule 5-1 --- .../test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected | 1 - 1 file changed, 1 deletion(-) diff --git a/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected b/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected index fa658750f0..f63f73c2d0 100644 --- a/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected +++ b/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected @@ -1,2 +1 @@ -| test.c:1:5:1:36 | iltiqzxgfqsgigwfuyntzghvzltueeeA | External identifer is nondistinct iltiqzxgfqsgigwfuyntzghvzltueeeA compared to $@. | test.c:2:5:2:36 | iltiqzxgfqsgigwfuyntzghvzltueeeB | iltiqzxgfqsgigwfuyntzghvzltueeeA | | test.c:2:5:2:36 | iltiqzxgfqsgigwfuyntzghvzltueeeB | External identifer is nondistinct iltiqzxgfqsgigwfuyntzghvzltueeeB compared to $@. | test.c:1:5:1:36 | iltiqzxgfqsgigwfuyntzghvzltueeeA | iltiqzxgfqsgigwfuyntzghvzltueeeB | From 6a48f42b6021083e2f3820aae01fb1b4894f540e Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Fri, 12 Aug 2022 06:54:01 -0400 Subject: [PATCH 13/24] Declarations1: fix 21-2 and DCL37-C to only look at user files --- .../declaredareservedidentifier/DeclaredAReservedIdentifier.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll b/cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll index f1fdf06862..85ad21cfae 100644 --- a/cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll +++ b/cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll @@ -14,6 +14,7 @@ Query getQuery() { result instanceof DeclaredAReservedIdentifierSharedQuery } query predicate problems(Element m, string message) { not isExcluded(m, getQuery()) and + exists(m.getFile().getRelativePath()) and exists(string name | ( m.(Macro).hasName(name) or From 87e70348514f10299f8740837410f8fd9abdbb77 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Fri, 12 Aug 2022 12:44:07 -0400 Subject: [PATCH 14/24] Declarations1: fix DCL31-C string match --- c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql index add104c51c..5f08cbbdb1 100644 --- a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql +++ b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql @@ -17,5 +17,6 @@ import codingstandards.c.cert from Declaration d where not isExcluded(d, Declarations1Package::declareIdentifiersBeforeUsingThemQuery()) and - exists(Specifier s | s = d.getASpecifier() and s.toString().regexpMatch("implicit_.*")) + exists(Specifier s | s = d.getASpecifier() and s.toString() = "implicit_int") and + exists(d.getFile().getRelativePath()) select d, "Declaration is missing a type specifier." From dfb1815cde4551ae21fbacd587d39888729388ae Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Fri, 12 Aug 2022 13:30:58 -0400 Subject: [PATCH 15/24] Declarations1: add inline notes to RULE-5-1 and RULE-5-4 for standards considered --- c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql | 3 +++ c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql index ffa572c234..507f3b8b9c 100644 --- a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql +++ b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql @@ -33,6 +33,9 @@ from ExternalIdentifiers d, ExternalIdentifiers d2 where not isExcluded(d, Declarations1Package::externalIdentifiersNotDistinctQuery()) and notSame(d, d2) and + //C99 states the first 31 characters of external identifiers are significant + //C90 states the first 6 characters of external identifiers are significant and case is not required to be significant + //C90 is not currently considered by this rule if d instanceof ExternalIdentifiersLong and d2 instanceof ExternalIdentifiersLong then d.getName().substring(0, 30) = d2.getName().substring(0, 30) else d.getName() = d2.getName() diff --git a/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql index 4040439860..8ac581b2bb 100644 --- a/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql +++ b/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql @@ -20,6 +20,10 @@ where not isExcluded(m, Declarations1Package::macroIdentifiersNotDistinctQuery()) and not m = m2 and ( + //C99 states the first 63 characters of macro identifiers are significant + //C90 states the first 31 characters of macro identifiers are significant and is not currently considered by this rule + //ie an identifier differing on the 32nd character would be indistinct for C90 but distinct for C99 + //and is currently not reported by this rule if m.getName().length() >= 64 then m.getName().substring(0, 62) = m2.getName().substring(0, 62) else m.getName() = m2.getName() From 8d8db4fc18a32ac9606bfda580f1e4b54bdea1e4 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 15 Aug 2022 11:57:07 -0400 Subject: [PATCH 16/24] Declarations1: remove unneeded predicates DCL31-C and DCL37-C --- c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql | 3 +-- .../DeclaredAReservedIdentifier.qll | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql index 5f08cbbdb1..0424d1ec6d 100644 --- a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql +++ b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql @@ -17,6 +17,5 @@ import codingstandards.c.cert from Declaration d where not isExcluded(d, Declarations1Package::declareIdentifiersBeforeUsingThemQuery()) and - exists(Specifier s | s = d.getASpecifier() and s.toString() = "implicit_int") and - exists(d.getFile().getRelativePath()) + d.hasSpecifier("implicit_int") select d, "Declaration is missing a type specifier." diff --git a/cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll b/cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll index 85ad21cfae..f1fdf06862 100644 --- a/cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll +++ b/cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll @@ -14,7 +14,6 @@ Query getQuery() { result instanceof DeclaredAReservedIdentifierSharedQuery } query predicate problems(Element m, string message) { not isExcluded(m, getQuery()) and - exists(m.getFile().getRelativePath()) and exists(string name | ( m.(Macro).hasName(name) or From a75a79a4069719d29093944996762ffbc9536fb1 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 15 Aug 2022 12:12:30 -0400 Subject: [PATCH 17/24] Declarations1: add testcases and improve type logic for DCL31-C --- .../DCL31-C/DeclareIdentifiersBeforeUsingThem.ql | 12 ++++++++++-- .../DeclareIdentifiersBeforeUsingThem.expected | 4 ++-- c/cert/test/rules/DCL31-C/test.c | 7 +++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql index 0424d1ec6d..bc6958337c 100644 --- a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql +++ b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql @@ -1,7 +1,8 @@ /** * @id c/cert/declare-identifiers-before-using-them * @name DCL31-C: Declare identifiers before using them - * @description Omission of type specifiers may not be supported by some compilers. + * @description Omission of type specifiers may not be supported by some + * compilers. * @kind problem * @precision very-high * @problem.severity error @@ -17,5 +18,12 @@ import codingstandards.c.cert from Declaration d where not isExcluded(d, Declarations1Package::declareIdentifiersBeforeUsingThemQuery()) and - d.hasSpecifier("implicit_int") + d.hasSpecifier("implicit_int") and + exists(Type t | + (d.(Variable).getType() = t or d.(Function).getType() = t) and + // Exclude "short" or "long", as opposed to "short int" or "long int". + t instanceof IntType and + // Exclude "signed" or "unsigned", as opposed to "signed int" or "unsigned int". + not exists(IntegralType it | it = t | it.isExplicitlySigned() or it.isExplicitlyUnsigned()) + ) select d, "Declaration is missing a type specifier." diff --git a/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected b/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected index d109ec77f4..03b2df0251 100644 --- a/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected +++ b/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected @@ -1,2 +1,2 @@ -| test.c:2:8:2:8 | g | Declaration is missing a type specifier. | -| test.c:6:1:6:1 | f | Declaration is missing a type specifier. | +| test.c:1:8:1:8 | g | Declaration is missing a type specifier. | +| test.c:5:1:5:1 | f | Declaration is missing a type specifier. | diff --git a/c/cert/test/rules/DCL31-C/test.c b/c/cert/test/rules/DCL31-C/test.c index ac901117bd..7442adb246 100644 --- a/c/cert/test/rules/DCL31-C/test.c +++ b/c/cert/test/rules/DCL31-C/test.c @@ -1,4 +1,3 @@ - extern g; // NON_COMPLIANT extern int g1; // COMPLIANT @@ -9,4 +8,8 @@ f(void) { // NON_COMPLIANT int f1(void) { // COMPLIANT return 1; -} \ No newline at end of file +} + +short g2; // COMPLIANT +long g3; // COMPLIANT +signed g4() { return 1; } // COMPLIANT From a3891e2c5ee7be6d8ea1f90616db0fc76d61111a Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 15 Aug 2022 13:59:27 -0400 Subject: [PATCH 18/24] Declarations1: improve alert messaages and substring predicate usage for RULE-5-1 and RULE-5-4 --- .../src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql | 6 ++++-- c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql | 4 ++-- .../rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected | 2 +- .../rules/RULE-5-4/MacroIdentifiersNotDistinct.expected | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql index 507f3b8b9c..ecca131fe3 100644 --- a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql +++ b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql @@ -37,6 +37,8 @@ where //C90 states the first 6 characters of external identifiers are significant and case is not required to be significant //C90 is not currently considered by this rule if d instanceof ExternalIdentifiersLong and d2 instanceof ExternalIdentifiersLong - then d.getName().substring(0, 30) = d2.getName().substring(0, 30) + then d.getName().prefix(31) = d2.getName().prefix(31) else d.getName() = d2.getName() -select d, "External identifer is nondistinct " + d.getName() + " compared to $@.", d2, d.getName() +select d, + "External identifer " + d.getName() + " is nondistinct in first 31 characters, compared to $@.", + d2, d2.getName() diff --git a/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql index 8ac581b2bb..1dd0fe196e 100644 --- a/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql +++ b/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql @@ -25,9 +25,9 @@ where //ie an identifier differing on the 32nd character would be indistinct for C90 but distinct for C99 //and is currently not reported by this rule if m.getName().length() >= 64 - then m.getName().substring(0, 62) = m2.getName().substring(0, 62) + then m.getName().prefix(63) = m2.getName().prefix(63) else m.getName() = m2.getName() ) and //reduce double report since both macros are in alert, arbitrary ordering m.getLocation().getStartLine() >= m2.getLocation().getStartLine() -select m, "Nondistinct macro identifer used " + m.getName() + " compared to $@.", m2, m2.getName() +select m, "Macro identifer " + m.getName() + " is nondistinct in first 63 characters, compared to $@.", m2, m2.getName() diff --git a/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected b/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected index f63f73c2d0..7cfe803888 100644 --- a/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected +++ b/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected @@ -1 +1 @@ -| test.c:2:5:2:36 | iltiqzxgfqsgigwfuyntzghvzltueeeB | External identifer is nondistinct iltiqzxgfqsgigwfuyntzghvzltueeeB compared to $@. | test.c:1:5:1:36 | iltiqzxgfqsgigwfuyntzghvzltueeeA | iltiqzxgfqsgigwfuyntzghvzltueeeB | +| test.c:2:5:2:36 | iltiqzxgfqsgigwfuyntzghvzltueeeB | External identifer iltiqzxgfqsgigwfuyntzghvzltueeeB is nondistinct in first 31 characters, compared to $@. | test.c:1:5:1:36 | iltiqzxgfqsgigwfuyntzghvzltueeeA | iltiqzxgfqsgigwfuyntzghvzltueeeA | diff --git a/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected b/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected index 41e4908d2f..12507b2d3f 100644 --- a/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected +++ b/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected @@ -1,2 +1,2 @@ -| test.c:2:1:2:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB | Nondistinct macro identifer used iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB compared to $@. | test.c:1:1:1:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA | iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA | -| test.c:8:1:8:31 | #define FUNCTION_MACRO(X) X + 1 | Nondistinct macro identifer used FUNCTION_MACRO compared to $@. | test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | FUNCTION_MACRO | +| test.c:2:1:2:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB | Macro identifer iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB is nondistinct in first 63 characters, compared to $@. | test.c:1:1:1:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA | iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA | +| test.c:8:1:8:31 | #define FUNCTION_MACRO(X) X + 1 | Macro identifer FUNCTION_MACRO is nondistinct in first 63 characters, compared to $@. | test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | FUNCTION_MACRO | From 4acfba8364eb343fc892d87d5493ad3940248bb7 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 15 Aug 2022 14:25:33 -0400 Subject: [PATCH 19/24] Declarations1: refactor RULE-5-1 --- .../ExternalIdentifiersNotDistinct.ql | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql index ecca131fe3..1a0ea2a6b2 100644 --- a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql +++ b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql @@ -18,27 +18,21 @@ import codingstandards.cpp.Linkage class ExternalIdentifiers extends Declaration { ExternalIdentifiers() { hasExternalLinkage(this) } -} -class ExternalIdentifiersLong extends ExternalIdentifiers { - ExternalIdentifiersLong() { this.getName().length() >= 32 } -} - -predicate notSame(ExternalIdentifiers d, ExternalIdentifiers d2) { - not d = d2 and - d.getLocation().getStartLine() >= d2.getLocation().getStartLine() + string getSignificantName() { + //C99 states the first 31 characters of external identifiers are significant + //C90 states the first 6 characters of external identifiers are significant and case is not required to be significant + //C90 is not currently considered by this rule + result = this.getName().prefix(31) + } } from ExternalIdentifiers d, ExternalIdentifiers d2 where not isExcluded(d, Declarations1Package::externalIdentifiersNotDistinctQuery()) and - notSame(d, d2) and - //C99 states the first 31 characters of external identifiers are significant - //C90 states the first 6 characters of external identifiers are significant and case is not required to be significant - //C90 is not currently considered by this rule - if d instanceof ExternalIdentifiersLong and d2 instanceof ExternalIdentifiersLong - then d.getName().prefix(31) = d2.getName().prefix(31) - else d.getName() = d2.getName() + not d = d2 and + d.getLocation().getStartLine() >= d2.getLocation().getStartLine() and + d.getSignificantName() = d2.getSignificantName() select d, "External identifer " + d.getName() + " is nondistinct in first 31 characters, compared to $@.", d2, d2.getName() From bc4acf4b22606d371927661143bd3a8ff17add2d Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 15 Aug 2022 14:56:30 -0400 Subject: [PATCH 20/24] Declarations1: refactor RULE-5-1 --- .../RULE-5-1/ExternalIdentifiersNotDistinct.ql | 17 +++++++++++++++-- c/misra/test/rules/RULE-5-1/test.c | 3 +++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql index 1a0ea2a6b2..6445ad091e 100644 --- a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql +++ b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql @@ -17,7 +17,17 @@ import codingstandards.c.misra import codingstandards.cpp.Linkage class ExternalIdentifiers extends Declaration { - ExternalIdentifiers() { hasExternalLinkage(this) } + ExternalIdentifiers() { + this.getName().length() > 31 and + hasExternalLinkage(this) and + getNamespace() instanceof GlobalNamespace and + not this.isFromTemplateInstantiation(_) and + not this.isFromUninstantiatedTemplate(_) and + not this.hasDeclaringType() and + not this instanceof UserType and + not this instanceof Operator and + not this.hasName("main") + } string getSignificantName() { //C99 states the first 31 characters of external identifiers are significant @@ -25,6 +35,8 @@ class ExternalIdentifiers extends Declaration { //C90 is not currently considered by this rule result = this.getName().prefix(31) } + + string getNonSignificantName() { result = this.getName().suffix(31) } } from ExternalIdentifiers d, ExternalIdentifiers d2 @@ -32,7 +44,8 @@ where not isExcluded(d, Declarations1Package::externalIdentifiersNotDistinctQuery()) and not d = d2 and d.getLocation().getStartLine() >= d2.getLocation().getStartLine() and - d.getSignificantName() = d2.getSignificantName() + d.getSignificantName() = d2.getSignificantName() and + not d.getNonSignificantName() = d2.getNonSignificantName() select d, "External identifer " + d.getName() + " is nondistinct in first 31 characters, compared to $@.", d2, d2.getName() diff --git a/c/misra/test/rules/RULE-5-1/test.c b/c/misra/test/rules/RULE-5-1/test.c index 623540657f..78f9f7fab6 100644 --- a/c/misra/test/rules/RULE-5-1/test.c +++ b/c/misra/test/rules/RULE-5-1/test.c @@ -1,5 +1,8 @@ int iltiqzxgfqsgigwfuyntzghvzltueeeA; // NON_COMPLIANT int iltiqzxgfqsgigwfuyntzghvzltueeeB; // NON_COMPLIANT +int iltiqzxgfqsgigwfuyntzghvzltueee; // COMPLIANT +int iltiqzxgfqsgigwfuyntzghvzltueee; // COMPLIANT + int var1; // COMPLIANT int var2; // COMPLIANT \ No newline at end of file From c05f9a8d30935fbc51ac5e01667d745bd131a618 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 15 Aug 2022 15:01:12 -0400 Subject: [PATCH 21/24] Declarations1: fix formatting DCL31-C --- c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql index bc6958337c..007eca3385 100644 --- a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql +++ b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql @@ -1,8 +1,7 @@ /** * @id c/cert/declare-identifiers-before-using-them * @name DCL31-C: Declare identifiers before using them - * @description Omission of type specifiers may not be supported by some - * compilers. + * @description Omission of type specifiers may not be supported by some compilers. * @kind problem * @precision very-high * @problem.severity error From d073b11945fe2d89eb7aacf3ed1b2bb863c3e7a2 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Tue, 16 Aug 2022 09:46:42 -0400 Subject: [PATCH 22/24] Declarations1: accept std lib result DCL37-C --- .../DeclaredAReservedIdentifier.expected | 1 + 1 file changed, 1 insertion(+) diff --git a/c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.expected b/c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.expected index 585c6d4c94..08e1688eb1 100644 --- a/c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.expected +++ b/c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.expected @@ -1,3 +1,4 @@ +| file://:0:0:0:0 | __va_list_tag | Reserved identifier '__va_list_tag' is declared. | | test.c:2:1:2:23 | #define _RESERVED_MACRO | Reserved identifier '_RESERVED_MACRO' is declared. | | test.c:11:8:11:9 | _s | Reserved identifier '_s' is declared. | | test.c:15:6:15:7 | _f | Reserved identifier '_f' is declared. | From 1cb417c70225412b27c6abf42d689ecd29f6c0ad Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Tue, 16 Aug 2022 10:05:10 -0400 Subject: [PATCH 23/24] Declarations1: minor query improvements --- c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql | 2 +- .../rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected | 4 ++-- .../rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql | 2 +- rule_packages/c/Declarations1.json | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql index 007eca3385..0d2e241957 100644 --- a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql +++ b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql @@ -25,4 +25,4 @@ where // Exclude "signed" or "unsigned", as opposed to "signed int" or "unsigned int". not exists(IntegralType it | it = t | it.isExplicitlySigned() or it.isExplicitlyUnsigned()) ) -select d, "Declaration is missing a type specifier." +select d, "Declaration " + d.getName() + " is missing a type specifier." diff --git a/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected b/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected index 03b2df0251..b10efab02c 100644 --- a/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected +++ b/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected @@ -1,2 +1,2 @@ -| test.c:1:8:1:8 | g | Declaration is missing a type specifier. | -| test.c:5:1:5:1 | f | Declaration is missing a type specifier. | +| test.c:1:8:1:8 | g | Declaration g is missing a type specifier. | +| test.c:5:1:5:1 | f | Declaration f is missing a type specifier. | diff --git a/c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql b/c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql index 7e196007a6..886e05f0ea 100644 --- a/c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql +++ b/c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql @@ -1,6 +1,6 @@ /** * @id c/misra/macro-identifier-not-distinct-from-parameter - * @name RULE-5-4: Macro identifiers shall be distinct + * @name RULE-5-4: Macro identifiers shall be distinct from paramters * @description Macros with the same name as their parameters are less readable. * @kind problem * @precision very-high diff --git a/rule_packages/c/Declarations1.json b/rule_packages/c/Declarations1.json index 1df0d038d6..49635a47ae 100644 --- a/rule_packages/c/Declarations1.json +++ b/rule_packages/c/Declarations1.json @@ -92,7 +92,7 @@ "readability" ], "implementation_scope": { - "description": "This query checks the first 31 characters of identifiers as significant, as per C99. This query does not consider universal or extended source characters.", + "description": "This query considers the first 31 characters of identifiers as significant, as per C99 and reports the case when names are longer than 31 characters and differ in those characters past the 31 first only. This query does not consider universal or extended source characters.", "items": [] } } @@ -124,7 +124,7 @@ { "description": "Macros with the same name as their parameters are less readable.", "kind": "problem", - "name": "Macro identifiers shall be distinct", + "name": "Macro identifiers shall be distinct from paramters", "precision": "very-high", "severity": "warning", "short_name": "MacroIdentifierNotDistinctFromParameter", From f45932d72010287df78adcf38be742bf5365a6ab Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Tue, 16 Aug 2022 10:46:55 -0400 Subject: [PATCH 24/24] Declarations1: improve RULE-5-1 --- .../rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql | 10 ++++------ .../RULE-5-1/ExternalIdentifiersNotDistinct.expected | 5 ++++- c/misra/test/rules/RULE-5-1/test.c | 12 +++++++++--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql index 6445ad091e..9dac244b3a 100644 --- a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql +++ b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql @@ -18,7 +18,7 @@ import codingstandards.cpp.Linkage class ExternalIdentifiers extends Declaration { ExternalIdentifiers() { - this.getName().length() > 31 and + this.getName().length() >= 31 and hasExternalLinkage(this) and getNamespace() instanceof GlobalNamespace and not this.isFromTemplateInstantiation(_) and @@ -35,8 +35,6 @@ class ExternalIdentifiers extends Declaration { //C90 is not currently considered by this rule result = this.getName().prefix(31) } - - string getNonSignificantName() { result = this.getName().suffix(31) } } from ExternalIdentifiers d, ExternalIdentifiers d2 @@ -45,7 +43,7 @@ where not d = d2 and d.getLocation().getStartLine() >= d2.getLocation().getStartLine() and d.getSignificantName() = d2.getSignificantName() and - not d.getNonSignificantName() = d2.getNonSignificantName() + not d.getName() = d2.getName() select d, - "External identifer " + d.getName() + " is nondistinct in first 31 characters, compared to $@.", - d2, d2.getName() + "External identifer " + d.getName() + + " is nondistinct in characters at or over 31 limit, compared to $@.", d2, d2.getName() diff --git a/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected b/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected index 7cfe803888..1e7d80876e 100644 --- a/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected +++ b/c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.expected @@ -1 +1,4 @@ -| test.c:2:5:2:36 | iltiqzxgfqsgigwfuyntzghvzltueeeB | External identifer iltiqzxgfqsgigwfuyntzghvzltueeeB is nondistinct in first 31 characters, compared to $@. | test.c:1:5:1:36 | iltiqzxgfqsgigwfuyntzghvzltueeeA | iltiqzxgfqsgigwfuyntzghvzltueeeA | +| test.c:2:5:2:36 | iltiqzxgfqsgigwfuyntzghvzltueeeB | External identifer iltiqzxgfqsgigwfuyntzghvzltueeeB is nondistinct in characters at or over 31 limit, compared to $@. | test.c:1:5:1:36 | iltiqzxgfqsgigwfuyntzghvzltueeeA | iltiqzxgfqsgigwfuyntzghvzltueeeA | +| test.c:5:5:5:35 | iltiqzxgfqsgigwfuyntzghvzltueea | External identifer iltiqzxgfqsgigwfuyntzghvzltueea is nondistinct in characters at or over 31 limit, compared to $@. | test.c:4:5:4:36 | iltiqzxgfqsgigwfuyntzghvzltueeaZ | iltiqzxgfqsgigwfuyntzghvzltueeaZ | +| test.c:8:5:8:35 | iltiqzxgfqsgigwfuyntzghvzltueee | External identifer iltiqzxgfqsgigwfuyntzghvzltueee is nondistinct in characters at or over 31 limit, compared to $@. | test.c:1:5:1:36 | iltiqzxgfqsgigwfuyntzghvzltueeeA | iltiqzxgfqsgigwfuyntzghvzltueeeA | +| test.c:8:5:8:35 | iltiqzxgfqsgigwfuyntzghvzltueee | External identifer iltiqzxgfqsgigwfuyntzghvzltueee is nondistinct in characters at or over 31 limit, compared to $@. | test.c:2:5:2:36 | iltiqzxgfqsgigwfuyntzghvzltueeeB | iltiqzxgfqsgigwfuyntzghvzltueeeB | diff --git a/c/misra/test/rules/RULE-5-1/test.c b/c/misra/test/rules/RULE-5-1/test.c index 78f9f7fab6..b0e2be532d 100644 --- a/c/misra/test/rules/RULE-5-1/test.c +++ b/c/misra/test/rules/RULE-5-1/test.c @@ -1,8 +1,14 @@ -int iltiqzxgfqsgigwfuyntzghvzltueeeA; // NON_COMPLIANT +int iltiqzxgfqsgigwfuyntzghvzltueeeA; // NON_COMPLIANT - length 32 int iltiqzxgfqsgigwfuyntzghvzltueeeB; // NON_COMPLIANT -int iltiqzxgfqsgigwfuyntzghvzltueee; // COMPLIANT -int iltiqzxgfqsgigwfuyntzghvzltueee; // COMPLIANT +int iltiqzxgfqsgigwfuyntzghvzltueeaZ; // NON_COMPLIANT - length 32 +int iltiqzxgfqsgigwfuyntzghvzltueea; // NON_COMPLIANT - length 31 + +int iltiqzxgfqsgigwfuyntzghvzltueee; // NON_COMPLIANT - length 31 +int iltiqzxgfqsgigwfuyntzghvzltueee; // NON_COMPLIANT + +int iltiqzxgfqsgigwfuyntzghvzltuee; // COMPLIANT - length 30 +int iltiqzxgfqsgigwfuyntzghvzltuee; // COMPLIANT int var1; // COMPLIANT int var2; // COMPLIANT \ No newline at end of file