From 24a99a13cc9b641c2bfbb9722cdfb9cddc0b4897 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Thu, 29 Sep 2022 11:48:23 -0400 Subject: [PATCH 1/7] Declarations3: add import RULE-5-3 --- .../IdentifierHidden.expected | 1 + .../identifierhidden/IdentifierHidden.ql | 2 ++ c/common/test/rules/identifierhidden/test.c | 0 .../src/rules/RULE-5-3/IdentifierHidingC.ql | 24 ++++++++++++++++ .../rules/RULE-5-3/IdentifierHidingC.testref | 1 + .../src/rules/A2-10-1/IdentifierHiding.ql | 11 +++----- .../test/rules/A2-10-1/IdentifierHiding.qlref | 1 - .../rules/A2-10-1/IdentifierHiding.testref | 1 + .../cpp/exclusions/c/Declarations3.qll | 25 +++++++++++++++++ .../cpp/exclusions/c/RuleMetadata.qll | 3 ++ .../identifierhidden/IdentifierHidden.qll | 20 +++++++++++++ .../IdentifierHidden.expected} | 0 .../identifierhidden/IdentifierHidden.ql | 2 ++ .../test/rules/identifierhidden}/test.cpp | 0 rule_packages/c/Declarations3.json | 28 +++++++++++++++++++ rule_packages/cpp/Naming.json | 1 + rules.csv | 2 +- 17 files changed, 113 insertions(+), 9 deletions(-) create mode 100644 c/common/test/rules/identifierhidden/IdentifierHidden.expected create mode 100644 c/common/test/rules/identifierhidden/IdentifierHidden.ql create mode 100644 c/common/test/rules/identifierhidden/test.c create mode 100644 c/misra/src/rules/RULE-5-3/IdentifierHidingC.ql create mode 100644 c/misra/test/rules/RULE-5-3/IdentifierHidingC.testref delete mode 100644 cpp/autosar/test/rules/A2-10-1/IdentifierHiding.qlref create mode 100644 cpp/autosar/test/rules/A2-10-1/IdentifierHiding.testref create mode 100644 cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll create mode 100644 cpp/common/src/codingstandards/cpp/rules/identifierhidden/IdentifierHidden.qll rename cpp/{autosar/test/rules/A2-10-1/IdentifierHiding.expected => common/test/rules/identifierhidden/IdentifierHidden.expected} (100%) create mode 100644 cpp/common/test/rules/identifierhidden/IdentifierHidden.ql rename cpp/{autosar/test/rules/A2-10-1 => common/test/rules/identifierhidden}/test.cpp (100%) create mode 100644 rule_packages/c/Declarations3.json diff --git a/c/common/test/rules/identifierhidden/IdentifierHidden.expected b/c/common/test/rules/identifierhidden/IdentifierHidden.expected new file mode 100644 index 0000000000..2ec1a0ac6c --- /dev/null +++ b/c/common/test/rules/identifierhidden/IdentifierHidden.expected @@ -0,0 +1 @@ +No expected results have yet been specified \ No newline at end of file diff --git a/c/common/test/rules/identifierhidden/IdentifierHidden.ql b/c/common/test/rules/identifierhidden/IdentifierHidden.ql new file mode 100644 index 0000000000..62abdd2163 --- /dev/null +++ b/c/common/test/rules/identifierhidden/IdentifierHidden.ql @@ -0,0 +1,2 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.identifierhidden.IdentifierHidden diff --git a/c/common/test/rules/identifierhidden/test.c b/c/common/test/rules/identifierhidden/test.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/c/misra/src/rules/RULE-5-3/IdentifierHidingC.ql b/c/misra/src/rules/RULE-5-3/IdentifierHidingC.ql new file mode 100644 index 0000000000..94d56367fe --- /dev/null +++ b/c/misra/src/rules/RULE-5-3/IdentifierHidingC.ql @@ -0,0 +1,24 @@ +/** + * @id c/misra/identifier-hiding-c + * @name RULE-5-3: An identifier declared in an inner scope shall not hide an identifier declared in an outer scope + * @description Use of an identifier declared in an inner scope with an identical name to an + * identifier in an outer scope can lead to inadvertent errors if the incorrect + * identifier is modified. + * @kind problem + * @precision very-high + * @problem.severity warning + * @tags external/misra/id/rule-5-3 + * readability + * maintainability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.cpp.rules.identifierhidden.IdentifierHidden + +class IdentifierHidingCQuery extends IdentifierHiddenSharedQuery { + IdentifierHidingCQuery() { + this = Declarations3Package::identifierHidingCQuery() + } +} diff --git a/c/misra/test/rules/RULE-5-3/IdentifierHidingC.testref b/c/misra/test/rules/RULE-5-3/IdentifierHidingC.testref new file mode 100644 index 0000000000..21c2628e82 --- /dev/null +++ b/c/misra/test/rules/RULE-5-3/IdentifierHidingC.testref @@ -0,0 +1 @@ +c/common/test/rules/identifierhidden/IdentifierHidden.ql \ No newline at end of file diff --git a/cpp/autosar/src/rules/A2-10-1/IdentifierHiding.ql b/cpp/autosar/src/rules/A2-10-1/IdentifierHiding.ql index e10d51a7e4..d5edf24832 100644 --- a/cpp/autosar/src/rules/A2-10-1/IdentifierHiding.ql +++ b/cpp/autosar/src/rules/A2-10-1/IdentifierHiding.ql @@ -19,11 +19,8 @@ import cpp import codingstandards.cpp.autosar -import codingstandards.cpp.Scope +import codingstandards.cpp.rules.identifierhidden.IdentifierHidden -from UserVariable v1, UserVariable v2 -where - not isExcluded(v1, NamingPackage::identifierHidingQuery()) and - not isExcluded(v2, NamingPackage::identifierHidingQuery()) and - hides(v1, v2) -select v2, "Variable is hiding variable $@.", v1, v1.getName() +class IdentifierHidingCQuery extends IdentifierHiddenSharedQuery { + IdentifierHidingCQuery() { this = NamingPackage::identifierHidingQuery() } +} diff --git a/cpp/autosar/test/rules/A2-10-1/IdentifierHiding.qlref b/cpp/autosar/test/rules/A2-10-1/IdentifierHiding.qlref deleted file mode 100644 index 3bc446954a..0000000000 --- a/cpp/autosar/test/rules/A2-10-1/IdentifierHiding.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/A2-10-1/IdentifierHiding.ql \ No newline at end of file diff --git a/cpp/autosar/test/rules/A2-10-1/IdentifierHiding.testref b/cpp/autosar/test/rules/A2-10-1/IdentifierHiding.testref new file mode 100644 index 0000000000..2f41afee3b --- /dev/null +++ b/cpp/autosar/test/rules/A2-10-1/IdentifierHiding.testref @@ -0,0 +1 @@ +cpp/common/test/rules/identifierhidden/IdentifierHidden.ql \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll new file mode 100644 index 0000000000..5afaa8f734 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll @@ -0,0 +1,25 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Declarations3Query = TIdentifierHidingCQuery() + +predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleId) { + query = + // `Query` instance for the `identifierHidingC` query + Declarations3Package::identifierHidingCQuery() and + queryId = + // `@id` for the `identifierHidingC` query + "c/misra/identifier-hiding-c" and + ruleId = "RULE-5-3" +} + +module Declarations3Package { + Query identifierHidingCQuery() { + //autogenerate `Query` type + result = + // `Query` type for `identifierHidingC` query + TQueryC(TDeclarations3PackageQuery(TIdentifierHidingCQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll index 24a7851467..e70d75f383 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll @@ -10,6 +10,7 @@ import Concurrency4 import Contracts1 import Declarations1 import Declarations2 +import Declarations3 import Expressions import IO1 import IO2 @@ -40,6 +41,7 @@ newtype TCQuery = TContracts1PackageQuery(Contracts1Query q) or TDeclarations1PackageQuery(Declarations1Query q) or TDeclarations2PackageQuery(Declarations2Query q) or + TDeclarations3PackageQuery(Declarations3Query q) or TExpressionsPackageQuery(ExpressionsQuery q) or TIO1PackageQuery(IO1Query q) or TIO2PackageQuery(IO2Query q) or @@ -70,6 +72,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId) { isContracts1QueryMetadata(query, queryId, ruleId) or isDeclarations1QueryMetadata(query, queryId, ruleId) or isDeclarations2QueryMetadata(query, queryId, ruleId) or + isDeclarations3QueryMetadata(query, queryId, ruleId) or isExpressionsQueryMetadata(query, queryId, ruleId) or isIO1QueryMetadata(query, queryId, ruleId) or isIO2QueryMetadata(query, queryId, ruleId) or diff --git a/cpp/common/src/codingstandards/cpp/rules/identifierhidden/IdentifierHidden.qll b/cpp/common/src/codingstandards/cpp/rules/identifierhidden/IdentifierHidden.qll new file mode 100644 index 0000000000..b3cadd6d2a --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/rules/identifierhidden/IdentifierHidden.qll @@ -0,0 +1,20 @@ +/** + * Provides a library which includes a `problems` predicate for reporting.... + */ + +import cpp +import codingstandards.cpp.Customizations +import codingstandards.cpp.Exclusions +import codingstandards.cpp.Scope + +abstract class IdentifierHiddenSharedQuery extends Query { } + +Query getQuery() { result instanceof IdentifierHiddenSharedQuery } + +query predicate problems(UserVariable v2, string message, UserVariable v1, string varName) { + not isExcluded(v1, getQuery()) and + not isExcluded(v2, getQuery()) and + hides(v1, v2) and + varName = v1.getName() and + message = "Variable is hiding variable $@." +} diff --git a/cpp/autosar/test/rules/A2-10-1/IdentifierHiding.expected b/cpp/common/test/rules/identifierhidden/IdentifierHidden.expected similarity index 100% rename from cpp/autosar/test/rules/A2-10-1/IdentifierHiding.expected rename to cpp/common/test/rules/identifierhidden/IdentifierHidden.expected diff --git a/cpp/common/test/rules/identifierhidden/IdentifierHidden.ql b/cpp/common/test/rules/identifierhidden/IdentifierHidden.ql new file mode 100644 index 0000000000..62abdd2163 --- /dev/null +++ b/cpp/common/test/rules/identifierhidden/IdentifierHidden.ql @@ -0,0 +1,2 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.identifierhidden.IdentifierHidden diff --git a/cpp/autosar/test/rules/A2-10-1/test.cpp b/cpp/common/test/rules/identifierhidden/test.cpp similarity index 100% rename from cpp/autosar/test/rules/A2-10-1/test.cpp rename to cpp/common/test/rules/identifierhidden/test.cpp diff --git a/rule_packages/c/Declarations3.json b/rule_packages/c/Declarations3.json new file mode 100644 index 0000000000..e382f58609 --- /dev/null +++ b/rule_packages/c/Declarations3.json @@ -0,0 +1,28 @@ +{ + "MISRA-C-2012": { + "RULE-5-3": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "Use of an identifier declared in an inner scope with an identical name to an identifier in an outer scope can lead to inadvertent errors if the incorrect identifier is modified.", + "name": "An identifier declared in an inner scope shall not hide an identifier declared in an outer scope", + "precision": "very-high", + "severity": "warning", + "short_name": "IdentifierHidingC", + "shared_implementation_short_name": "IdentifierHidden", + "tags": [ + "readability", + "maintainability" + ], + "implementation_scope": { + "description": "This query does not consider C90 or C99 definitions of significant name and instead uses full name matches only.", + "items": [] + } + } + ], + "title": "An identifier declared in an inner scope shall not hide an identifier declared in an outer scope." + } + } +} \ No newline at end of file diff --git a/rule_packages/cpp/Naming.json b/rule_packages/cpp/Naming.json index 82b20008df..e59f007975 100644 --- a/rule_packages/cpp/Naming.json +++ b/rule_packages/cpp/Naming.json @@ -39,6 +39,7 @@ "precision": "very-high", "severity": "warning", "short_name": "IdentifierHiding", + "shared_implementation_short_name": "IdentifierHidden", "tags": [ "readability", "maintainability" diff --git a/rules.csv b/rules.csv index 0a97b03044..495d36c263 100755 --- a/rules.csv +++ b/rules.csv @@ -633,7 +633,7 @@ c,MISRA-C-2012,RULE-4-1,Yes,Required,,,Octal and hexadecimal escape sequences sh 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,,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-3,Yes,Required,,,An identifier declared in an inner scope shall not hide an identifier declared in an outer scope,A2-10-1,Declarations3,Import, 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, From d86b532f91de81b019b76a5ca0201d03ce383900 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Thu, 29 Sep 2022 14:45:29 -0400 Subject: [PATCH 2/7] Declarations3: add missing testcase prev RULE-5-3 --- .../IdentifierHidden.expected | 6 +++- c/common/test/rules/identifierhidden/test.c | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/c/common/test/rules/identifierhidden/IdentifierHidden.expected b/c/common/test/rules/identifierhidden/IdentifierHidden.expected index 2ec1a0ac6c..67809ee003 100644 --- a/c/common/test/rules/identifierhidden/IdentifierHidden.expected +++ b/c/common/test/rules/identifierhidden/IdentifierHidden.expected @@ -1 +1,5 @@ -No expected results have yet been specified \ No newline at end of file +| test.c:4:7:4:9 | id1 | Variable is hiding variable $@. | test.c:1:5:1:7 | id1 | id1 | +| test.c:7:13:7:15 | id1 | Variable is hiding variable $@. | test.c:1:5:1:7 | id1 | id1 | +| test.c:10:12:10:14 | id1 | Variable is hiding variable $@. | test.c:1:5:1:7 | id1 | id1 | +| test.c:11:14:11:16 | id1 | Variable is hiding variable $@. | test.c:10:12:10:14 | id1 | id1 | +| test.c:24:24:24:26 | id2 | Variable is hiding variable $@. | test.c:22:5:22:7 | id2 | id2 | diff --git a/c/common/test/rules/identifierhidden/test.c b/c/common/test/rules/identifierhidden/test.c index e69de29bb2..b5cd8040b9 100644 --- a/c/common/test/rules/identifierhidden/test.c +++ b/c/common/test/rules/identifierhidden/test.c @@ -0,0 +1,30 @@ +int id1; + +void f1() { + int id1; // NON_COMPLIANT +} + +void f2(int id1) {} // NON_COMPLIANT + +void f3() { + for (int id1; id1 < 1; id1++) { // NON_COMPLIANT + for (int id1; id1 < 1; id1++) { + } // NON_COMPLIANT + } +} + +struct astruct { + int id1; +}; + +extern void g(struct astruct *p); + +int id2 = 0; + +void f4(struct astruct id2) { // NON_COMPLIANT + g(&id2); +} + +void f5(struct astruct id3) { // COMPLIANT + g(&id2); +} \ No newline at end of file From 8ca4a3ee3eefb241f0d7abc1a368522b804c8275 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 3 Oct 2022 13:55:49 -0400 Subject: [PATCH 3/7] Declarations3: add RULE-5-6 --- .../rules/RULE-5-6/TypedefNameNotUnique.ql | 40 +++++++++++++++++++ .../RULE-5-6/TypedefNameNotUnique.expected | 2 + .../rules/RULE-5-6/TypedefNameNotUnique.qlref | 1 + c/misra/test/rules/RULE-5-6/test.c | 32 +++++++++++++++ c/misra/test/rules/RULE-5-6/test.h | 1 + c/misra/test/rules/RULE-5-6/test1.c | 1 + .../cpp/exclusions/c/Declarations3.qll | 19 ++++++++- rule_packages/c/Declarations3.json | 20 ++++++++++ rules.csv | 2 +- 9 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql create mode 100644 c/misra/test/rules/RULE-5-6/TypedefNameNotUnique.expected create mode 100644 c/misra/test/rules/RULE-5-6/TypedefNameNotUnique.qlref create mode 100644 c/misra/test/rules/RULE-5-6/test.c create mode 100644 c/misra/test/rules/RULE-5-6/test.h create mode 100644 c/misra/test/rules/RULE-5-6/test1.c diff --git a/c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql b/c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql new file mode 100644 index 0000000000..fc00614e97 --- /dev/null +++ b/c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql @@ -0,0 +1,40 @@ +/** + * @id c/misra/typedef-name-not-unique + * @name RULE-5-6: A typedef name shall be a unique identifier + * @description Reusing a typedef name compared to the name of any other identifier can cause + * confusion and make code harder to read. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-5-6 + * readability + * maintainability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra + +//exception cases additional to rule description +class InterestingIdentifiers extends Declaration { + InterestingIdentifiers() { + not this.isFromTemplateInstantiation(_) and + not this.isFromUninstantiatedTemplate(_) and + not this instanceof TemplateParameter and + not this.hasDeclaringType() and + not this instanceof Operator and + not this.hasName("main") and + exists(this.getADeclarationLocation()) + } +} + +from TypedefType t, InterestingIdentifiers d +where + not isExcluded(t, Declarations3Package::typedefNameNotUniqueQuery()) and + not isExcluded(d, Declarations3Package::typedefNameNotUniqueQuery()) and + not t.getADeclarationLocation() = d.getADeclarationLocation() and + t.getName() = d.getName() and + //exception cases + not d.(Struct).getName() = t.getBaseType().toString() and + not d.(Enum).getName() = t.getBaseType().toString() +select t, "Typedef name is nonunique compared to $@.", d, d.getName() diff --git a/c/misra/test/rules/RULE-5-6/TypedefNameNotUnique.expected b/c/misra/test/rules/RULE-5-6/TypedefNameNotUnique.expected new file mode 100644 index 0000000000..890f1ac642 --- /dev/null +++ b/c/misra/test/rules/RULE-5-6/TypedefNameNotUnique.expected @@ -0,0 +1,2 @@ +| test.c:11:15:11:19 | test1 | Typedef name is nonunique compared to $@. | test.c:13:17:13:21 | test1 | test1 | +| test.c:30:3:30:7 | chain | Typedef name is nonunique compared to $@. | test.c:26:10:26:14 | chain | chain | diff --git a/c/misra/test/rules/RULE-5-6/TypedefNameNotUnique.qlref b/c/misra/test/rules/RULE-5-6/TypedefNameNotUnique.qlref new file mode 100644 index 0000000000..841896df65 --- /dev/null +++ b/c/misra/test/rules/RULE-5-6/TypedefNameNotUnique.qlref @@ -0,0 +1 @@ +rules/RULE-5-6/TypedefNameNotUnique.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-5-6/test.c b/c/misra/test/rules/RULE-5-6/test.c new file mode 100644 index 0000000000..0505f3d811 --- /dev/null +++ b/c/misra/test/rules/RULE-5-6/test.c @@ -0,0 +1,32 @@ +#include "test.h" +void f() { + { + typedef unsigned char test; // NON_COMPLIANT + } + { + typedef unsigned char test; // NON_COMPLIANT + } +} + +typedef float test1; // NON_COMPLIANT + +void f2() { int test1 = 0; } + +typedef struct list { + int i; +} list; // COMPLIANT + +typedef struct BIGList1 { + int i; +} list1; // COMPLIANT + +typedef enum enum1 { testenum } enum1; // COMPLIANT + +typedef struct { + struct chain { + int ii; + } s1; + int i; +} chain; // NON_COMPLIANT + +typedef void (*pointercase)(int i); // COMPLIANT \ No newline at end of file diff --git a/c/misra/test/rules/RULE-5-6/test.h b/c/misra/test/rules/RULE-5-6/test.h new file mode 100644 index 0000000000..142aa17704 --- /dev/null +++ b/c/misra/test/rules/RULE-5-6/test.h @@ -0,0 +1 @@ +typedef int headertest; // COMPLIANT \ No newline at end of file diff --git a/c/misra/test/rules/RULE-5-6/test1.c b/c/misra/test/rules/RULE-5-6/test1.c new file mode 100644 index 0000000000..91ab081c47 --- /dev/null +++ b/c/misra/test/rules/RULE-5-6/test1.c @@ -0,0 +1 @@ +#include "test.h" \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll index 5afaa8f734..6ec5ba51ea 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll @@ -3,7 +3,9 @@ import cpp import RuleMetadata import codingstandards.cpp.exclusions.RuleMetadata -newtype Declarations3Query = TIdentifierHidingCQuery() +newtype Declarations3Query = + TIdentifierHidingCQuery() or + TTypedefNameNotUniqueQuery() predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleId) { query = @@ -13,6 +15,14 @@ predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleI // `@id` for the `identifierHidingC` query "c/misra/identifier-hiding-c" and ruleId = "RULE-5-3" + or + query = + // `Query` instance for the `typedefNameNotUnique` query + Declarations3Package::typedefNameNotUniqueQuery() and + queryId = + // `@id` for the `typedefNameNotUnique` query + "c/misra/typedef-name-not-unique" and + ruleId = "RULE-5-6" } module Declarations3Package { @@ -22,4 +32,11 @@ module Declarations3Package { // `Query` type for `identifierHidingC` query TQueryC(TDeclarations3PackageQuery(TIdentifierHidingCQuery())) } + + Query typedefNameNotUniqueQuery() { + //autogenerate `Query` type + result = + // `Query` type for `typedefNameNotUnique` query + TQueryC(TDeclarations3PackageQuery(TTypedefNameNotUniqueQuery())) + } } diff --git a/rule_packages/c/Declarations3.json b/rule_packages/c/Declarations3.json index e382f58609..08f312d23e 100644 --- a/rule_packages/c/Declarations3.json +++ b/rule_packages/c/Declarations3.json @@ -23,6 +23,26 @@ } ], "title": "An identifier declared in an inner scope shall not hide an identifier declared in an outer scope." + }, + "RULE-5-6": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "Reusing a typedef name compared to the name of any other identifier can cause confusion and make code harder to read.", + "kind": "problem", + "name": "A typedef name shall be a unique identifier", + "precision": "very-high", + "severity": "error", + "short_name": "TypedefNameNotUnique", + "tags": [ + "readability", + "maintainability" + ] + } + ], + "title": "A typedef name shall be a unique identifier" } } } \ No newline at end of file diff --git a/rules.csv b/rules.csv index 495d36c263..c7538caeb5 100755 --- a/rules.csv +++ b/rules.csv @@ -636,7 +636,7 @@ c,MISRA-C-2012,RULE-5-2,Yes,Required,,,Identifiers declared in the same scope an 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,Declarations3,Import, 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-6,Yes,Required,,,A typedef name shall be a unique identifier,,Declarations3,Easy, c,MISRA-C-2012,RULE-5-7,Yes,Required,,,A tag name shall be a unique identifier,,Declarations,Easy, c,MISRA-C-2012,RULE-5-8,Yes,Required,,,Identifiers that define objects or functions with external linkage shall be unique,,Declarations,Easy, c,MISRA-C-2012,RULE-5-9,Yes,Advisory,,,Identifiers that define objects or functions with internal linkage should be unique,,Declarations,Easy, From 70c6b4ef4babcbb265da8f0174ecf3b6bf7d7c2b Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 3 Oct 2022 16:07:58 -0400 Subject: [PATCH 4/7] Declarations3: add RULE-5-7 and fix testcase RULE-5-6 --- .../src/codingstandards/c/Identifiers.qll | 14 ++++++++ .../rules/RULE-5-6/TypedefNameNotUnique.ql | 14 +------- .../src/rules/RULE-5-7/TagNameNotUnique.ql | 28 ++++++++++++++++ c/misra/test/rules/RULE-5-6/test.c | 4 +-- .../rules/RULE-5-7/TagNameNotUnique.expected | 4 +++ .../rules/RULE-5-7/TagNameNotUnique.qlref | 1 + c/misra/test/rules/RULE-5-7/test.c | 33 +++++++++++++++++++ .../cpp/exclusions/c/Declarations3.qll | 18 +++++++++- rule_packages/c/Declarations3.json | 20 +++++++++++ rules.csv | 2 +- 10 files changed, 120 insertions(+), 18 deletions(-) create mode 100644 c/common/src/codingstandards/c/Identifiers.qll create mode 100644 c/misra/src/rules/RULE-5-7/TagNameNotUnique.ql create mode 100644 c/misra/test/rules/RULE-5-7/TagNameNotUnique.expected create mode 100644 c/misra/test/rules/RULE-5-7/TagNameNotUnique.qlref create mode 100644 c/misra/test/rules/RULE-5-7/test.c diff --git a/c/common/src/codingstandards/c/Identifiers.qll b/c/common/src/codingstandards/c/Identifiers.qll new file mode 100644 index 0000000000..51c024028c --- /dev/null +++ b/c/common/src/codingstandards/c/Identifiers.qll @@ -0,0 +1,14 @@ +import cpp + +//Identifiers that are candidates for checking uniqueness +class InterestingIdentifiers extends Declaration { + InterestingIdentifiers() { + not this.isFromTemplateInstantiation(_) and + not this.isFromUninstantiatedTemplate(_) and + not this instanceof TemplateParameter and + not this.hasDeclaringType() and + not this instanceof Operator and + not this.hasName("main") and + exists(this.getADeclarationLocation()) + } + } \ No newline at end of file diff --git a/c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql b/c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql index fc00614e97..eebdabe956 100644 --- a/c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql +++ b/c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql @@ -14,19 +14,7 @@ import cpp import codingstandards.c.misra - -//exception cases additional to rule description -class InterestingIdentifiers extends Declaration { - InterestingIdentifiers() { - not this.isFromTemplateInstantiation(_) and - not this.isFromUninstantiatedTemplate(_) and - not this instanceof TemplateParameter and - not this.hasDeclaringType() and - not this instanceof Operator and - not this.hasName("main") and - exists(this.getADeclarationLocation()) - } -} +import codingstandards.c.Identifiers from TypedefType t, InterestingIdentifiers d where diff --git a/c/misra/src/rules/RULE-5-7/TagNameNotUnique.ql b/c/misra/src/rules/RULE-5-7/TagNameNotUnique.ql new file mode 100644 index 0000000000..f7c005d7fa --- /dev/null +++ b/c/misra/src/rules/RULE-5-7/TagNameNotUnique.ql @@ -0,0 +1,28 @@ +/** + * @id c/misra/tag-name-not-unique + * @name RULE-5-7: A tag name shall be a unique identifier + * @description Reusing a tag name compared to the name of any tag can cause confusion and make code + * harder to read. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-5-7 + * readability + * maintainability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.c.Identifiers + +from Struct s, InterestingIdentifiers s2 +where + not isExcluded(s, Declarations3Package::tagNameNotUniqueQuery()) and + not isExcluded(s2, Declarations3Package::tagNameNotUniqueQuery()) and + not s = s2 and + s.getName() = s2.getName() and + not s.getName() = "struct " and + not s.getName() = "union " and + not s.getName() = s2.(TypedefType).getBaseType().toString() +select s, "Tag name is nonunique compared to $@.", s2, s2.getName() diff --git a/c/misra/test/rules/RULE-5-6/test.c b/c/misra/test/rules/RULE-5-6/test.c index 0505f3d811..6cc705e8e6 100644 --- a/c/misra/test/rules/RULE-5-6/test.c +++ b/c/misra/test/rules/RULE-5-6/test.c @@ -27,6 +27,4 @@ typedef struct { int ii; } s1; int i; -} chain; // NON_COMPLIANT - -typedef void (*pointercase)(int i); // COMPLIANT \ No newline at end of file +} chain; // NON_COMPLIANT \ No newline at end of file diff --git a/c/misra/test/rules/RULE-5-7/TagNameNotUnique.expected b/c/misra/test/rules/RULE-5-7/TagNameNotUnique.expected new file mode 100644 index 0000000000..05d20dcfaa --- /dev/null +++ b/c/misra/test/rules/RULE-5-7/TagNameNotUnique.expected @@ -0,0 +1,4 @@ +| test.c:5:8:5:9 | s1 | Tag name is nonunique compared to $@. | test.c:12:10:12:11 | s1 | s1 | +| test.c:5:8:5:9 | s1 | Tag name is nonunique compared to $@. | test.c:17:17:17:18 | s1 | s1 | +| test.c:12:10:12:11 | s1 | Tag name is nonunique compared to $@. | test.c:5:8:5:9 | s1 | s1 | +| test.c:12:10:12:11 | s1 | Tag name is nonunique compared to $@. | test.c:17:17:17:18 | s1 | s1 | diff --git a/c/misra/test/rules/RULE-5-7/TagNameNotUnique.qlref b/c/misra/test/rules/RULE-5-7/TagNameNotUnique.qlref new file mode 100644 index 0000000000..bbd4982cc9 --- /dev/null +++ b/c/misra/test/rules/RULE-5-7/TagNameNotUnique.qlref @@ -0,0 +1 @@ +rules/RULE-5-7/TagNameNotUnique.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-5-7/test.c b/c/misra/test/rules/RULE-5-7/test.c new file mode 100644 index 0000000000..6d1b424c60 --- /dev/null +++ b/c/misra/test/rules/RULE-5-7/test.c @@ -0,0 +1,33 @@ +typedef struct s { + int i; +} s; // COMPLIANT + +struct s1 { // NON_COMPLIANT + int i; +}; + +struct s1 a1 = {0}; // COMPLIANT + +void f() { + struct s1 { // NON_COMPLIANT + int i; + }; +} + +void f1() { int s1 = 0; } + +typedef struct { + int i; +} sunnamed; // COMPLIANT + +typedef struct { + int i; +} sunnamed2; // COMPLIANT + +typedef union { + int i; +} U; // COMPLIANT + +typedef union { + int i; +}; // COMPLIANT \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll index 6ec5ba51ea..587226d545 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll @@ -5,7 +5,8 @@ import codingstandards.cpp.exclusions.RuleMetadata newtype Declarations3Query = TIdentifierHidingCQuery() or - TTypedefNameNotUniqueQuery() + TTypedefNameNotUniqueQuery() or + TTagNameNotUniqueQuery() predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleId) { query = @@ -23,6 +24,14 @@ predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleI // `@id` for the `typedefNameNotUnique` query "c/misra/typedef-name-not-unique" and ruleId = "RULE-5-6" + or + query = + // `Query` instance for the `tagNameNotUnique` query + Declarations3Package::tagNameNotUniqueQuery() and + queryId = + // `@id` for the `tagNameNotUnique` query + "c/misra/tag-name-not-unique" and + ruleId = "RULE-5-7" } module Declarations3Package { @@ -39,4 +48,11 @@ module Declarations3Package { // `Query` type for `typedefNameNotUnique` query TQueryC(TDeclarations3PackageQuery(TTypedefNameNotUniqueQuery())) } + + Query tagNameNotUniqueQuery() { + //autogenerate `Query` type + result = + // `Query` type for `tagNameNotUnique` query + TQueryC(TDeclarations3PackageQuery(TTagNameNotUniqueQuery())) + } } diff --git a/rule_packages/c/Declarations3.json b/rule_packages/c/Declarations3.json index 08f312d23e..9144fbf9e7 100644 --- a/rule_packages/c/Declarations3.json +++ b/rule_packages/c/Declarations3.json @@ -43,6 +43,26 @@ } ], "title": "A typedef name shall be a unique identifier" + }, + "RULE-5-7": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "Reusing a tag name compared to the name of any tag can cause confusion and make code harder to read.", + "kind": "problem", + "name": "A tag name shall be a unique identifier", + "precision": "very-high", + "severity": "error", + "short_name": "TagNameNotUnique", + "tags": [ + "readability", + "maintainability" + ] + } + ], + "title": "A tag name shall be a unique identifier" } } } \ No newline at end of file diff --git a/rules.csv b/rules.csv index c7538caeb5..ae65c2dc55 100755 --- a/rules.csv +++ b/rules.csv @@ -637,7 +637,7 @@ c,MISRA-C-2012,RULE-5-3,Yes,Required,,,An identifier declared in an inner scope 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,,Declarations3,Easy, -c,MISRA-C-2012,RULE-5-7,Yes,Required,,,A tag 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,,Declarations3,Easy, c,MISRA-C-2012,RULE-5-8,Yes,Required,,,Identifiers that define objects or functions with external linkage shall be unique,,Declarations,Easy, c,MISRA-C-2012,RULE-5-9,Yes,Advisory,,,Identifiers that define objects or functions with internal linkage should be unique,,Declarations,Easy, c,MISRA-C-2012,RULE-6-1,Yes,Required,,,Bit-fields shall only be declared with an appropriate type,M9-6-4,Types,Medium, From c388baee179aaf5779a930e9dda0b3fcf83ed101 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Mon, 3 Oct 2022 16:09:30 -0400 Subject: [PATCH 5/7] Declarations3: fix format Identifiers lib --- .../src/codingstandards/c/Identifiers.qll | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/c/common/src/codingstandards/c/Identifiers.qll b/c/common/src/codingstandards/c/Identifiers.qll index 51c024028c..e7d7787fa4 100644 --- a/c/common/src/codingstandards/c/Identifiers.qll +++ b/c/common/src/codingstandards/c/Identifiers.qll @@ -2,13 +2,13 @@ import cpp //Identifiers that are candidates for checking uniqueness class InterestingIdentifiers extends Declaration { - InterestingIdentifiers() { - not this.isFromTemplateInstantiation(_) and - not this.isFromUninstantiatedTemplate(_) and - not this instanceof TemplateParameter and - not this.hasDeclaringType() and - not this instanceof Operator and - not this.hasName("main") and - exists(this.getADeclarationLocation()) - } - } \ No newline at end of file + InterestingIdentifiers() { + not this.isFromTemplateInstantiation(_) and + not this.isFromUninstantiatedTemplate(_) and + not this instanceof TemplateParameter and + not this.hasDeclaringType() and + not this instanceof Operator and + not this.hasName("main") and + exists(this.getADeclarationLocation()) + } +} From 311eb925e35cc30c090eb764c1bb92b173074f6f Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Wed, 5 Oct 2022 12:20:38 -0400 Subject: [PATCH 6/7] Declarations3: add RULE-5-5 --- .../src/codingstandards/c/Identifiers.qll | 2 ++ .../IdentifiersNotDistinctFromMacroNames.ql | 31 +++++++++++++++++++ ...ntifiersNotDistinctFromMacroNames.expected | 2 ++ ...IdentifiersNotDistinctFromMacroNames.qlref | 1 + c/misra/test/rules/RULE-5-5/test.c | 7 +++++ .../cpp/exclusions/c/Declarations3.qll | 16 ++++++++++ rule_packages/c/Declarations3.json | 20 ++++++++++++ rules.csv | 2 +- 8 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 c/misra/src/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.ql create mode 100644 c/misra/test/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.expected create mode 100644 c/misra/test/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.qlref create mode 100644 c/misra/test/rules/RULE-5-5/test.c diff --git a/c/common/src/codingstandards/c/Identifiers.qll b/c/common/src/codingstandards/c/Identifiers.qll index e7d7787fa4..c100747cfb 100644 --- a/c/common/src/codingstandards/c/Identifiers.qll +++ b/c/common/src/codingstandards/c/Identifiers.qll @@ -11,4 +11,6 @@ class InterestingIdentifiers extends Declaration { not this.hasName("main") and exists(this.getADeclarationLocation()) } + + string getSignificantName() { result = this.getName().prefix(31) } } diff --git a/c/misra/src/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.ql b/c/misra/src/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.ql new file mode 100644 index 0000000000..ff0b730e1f --- /dev/null +++ b/c/misra/src/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.ql @@ -0,0 +1,31 @@ +/** + * @id c/misra/identifiers-not-distinct-from-macro-names + * @name RULE-5-5: Identifiers shall be distinct from macro names + * @description Reusing a macro name compared to the name of any other identifier can cause + * confusion and make code harder to read. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-5-5 + * readability + * maintainability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.c.Identifiers + +from Macro m, InterestingIdentifiers i, string mName, string iName +where + not isExcluded(m, Declarations3Package::identifiersNotDistinctFromMacroNamesQuery()) and + not isExcluded(i, Declarations3Package::identifiersNotDistinctFromMacroNamesQuery()) and + mName = iName 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 m.getName().length() > 31 then mName = m.getName().prefix(31) else mName = m.getName() + ) and + if i.getName().length() > 31 then iName = i.getSignificantName() else iName = i.getName() +select m, "Macro name is nonunique compared to $@.", i, i.getName() diff --git a/c/misra/test/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.expected b/c/misra/test/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.expected new file mode 100644 index 0000000000..bf8cf218d8 --- /dev/null +++ b/c/misra/test/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.expected @@ -0,0 +1,2 @@ +| test.c:1:1:1:23 | #define Sum(x,y) x + y | Macro name is nonunique compared to $@. | test.c:4:5:4:7 | Sum | Sum | +| test.c:6:1:6:42 | #define iltiqzxgfqsgigwfuyntzghvzltueeaZ ; | Macro name is nonunique compared to $@. | test.c:7:12:7:43 | iltiqzxgfqsgigwfuyntzghvzltueeaQ | iltiqzxgfqsgigwfuyntzghvzltueeaQ | diff --git a/c/misra/test/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.qlref b/c/misra/test/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.qlref new file mode 100644 index 0000000000..1cc5276d4a --- /dev/null +++ b/c/misra/test/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.qlref @@ -0,0 +1 @@ +rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-5-5/test.c b/c/misra/test/rules/RULE-5-5/test.c new file mode 100644 index 0000000000..6ae5c4c871 --- /dev/null +++ b/c/misra/test/rules/RULE-5-5/test.c @@ -0,0 +1,7 @@ +#define Sum(x, y) x + y // NON_COMPLIANT +#undef Sum + +int Sum; + +#define iltiqzxgfqsgigwfuyntzghvzltueeaZ ; // NON_COMPLIANT - length 32 +static int iltiqzxgfqsgigwfuyntzghvzltueeaQ; // NON_COMPLIANT - length 32 \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll index 587226d545..d31011234a 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll @@ -5,6 +5,7 @@ import codingstandards.cpp.exclusions.RuleMetadata newtype Declarations3Query = TIdentifierHidingCQuery() or + TIdentifiersNotDistinctFromMacroNamesQuery() or TTypedefNameNotUniqueQuery() or TTagNameNotUniqueQuery() @@ -17,6 +18,14 @@ predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleI "c/misra/identifier-hiding-c" and ruleId = "RULE-5-3" or + query = + // `Query` instance for the `identifiersNotDistinctFromMacroNames` query + Declarations3Package::identifiersNotDistinctFromMacroNamesQuery() and + queryId = + // `@id` for the `identifiersNotDistinctFromMacroNames` query + "c/misra/identifiers-not-distinct-from-macro-names" and + ruleId = "RULE-5-5" + or query = // `Query` instance for the `typedefNameNotUnique` query Declarations3Package::typedefNameNotUniqueQuery() and @@ -42,6 +51,13 @@ module Declarations3Package { TQueryC(TDeclarations3PackageQuery(TIdentifierHidingCQuery())) } + Query identifiersNotDistinctFromMacroNamesQuery() { + //autogenerate `Query` type + result = + // `Query` type for `identifiersNotDistinctFromMacroNames` query + TQueryC(TDeclarations3PackageQuery(TIdentifiersNotDistinctFromMacroNamesQuery())) + } + Query typedefNameNotUniqueQuery() { //autogenerate `Query` type result = diff --git a/rule_packages/c/Declarations3.json b/rule_packages/c/Declarations3.json index 9144fbf9e7..b6307c71cb 100644 --- a/rule_packages/c/Declarations3.json +++ b/rule_packages/c/Declarations3.json @@ -24,6 +24,26 @@ ], "title": "An identifier declared in an inner scope shall not hide an identifier declared in an outer scope." }, + "RULE-5-5": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "Reusing a macro name compared to the name of any other identifier can cause confusion and make code harder to read.", + "kind": "problem", + "name": "Identifiers shall be distinct from macro names", + "precision": "very-high", + "severity": "error", + "short_name": "IdentifiersNotDistinctFromMacroNames", + "tags": [ + "readability", + "maintainability" + ] + } + ], + "title": "Identifiers shall be distinct from macro names" + }, "RULE-5-6": { "properties": { "obligation": "required" diff --git a/rules.csv b/rules.csv index ae65c2dc55..aa0f3f5245 100755 --- a/rules.csv +++ b/rules.csv @@ -635,7 +635,7 @@ c,MISRA-C-2012,RULE-5-1,Yes,Required,,,External identifiers shall be distinct,,D 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,Declarations3,Import, 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-5,Yes,Required,,,Identifiers shall be distinct from macro names,,Declarations3,Easy, c,MISRA-C-2012,RULE-5-6,Yes,Required,,,A typedef name shall be a unique identifier,,Declarations3,Easy, c,MISRA-C-2012,RULE-5-7,Yes,Required,,,A tag name shall be a unique identifier,,Declarations3,Easy, c,MISRA-C-2012,RULE-5-8,Yes,Required,,,Identifiers that define objects or functions with external linkage shall be unique,,Declarations,Easy, From 68304ab4672c03d327e0267083ac836d2822a416 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Wed, 5 Oct 2022 14:32:32 -0400 Subject: [PATCH 7/7] Declarations3: add shared RULE-8-1 --- .../DeclareIdentifiersBeforeUsingThem.md | 2 +- .../DeclareIdentifiersBeforeUsingThem.ql | 18 +++++-------- .../DeclareIdentifiersBeforeUsingThem.qlref | 1 - .../DeclareIdentifiersBeforeUsingThem.testref | 1 + .../rules/typeomitted/TypeOmitted.expected} | 0 .../test/rules/typeomitted/TypeOmitted.ql | 2 ++ .../test/rules/typeomitted}/test.c | 10 ++++++++ .../rules/RULE-8-1/ExplicitlyDeclareTypes.ql | 20 +++++++++++++++ .../RULE-8-1/ExplicitlyDeclareTypes.testref | 1 + .../cpp/exclusions/c/Declarations3.qll | 18 ++++++++++++- .../cpp/rules/typeomitted/TypeOmitted.qll | 24 ++++++++++++++++++ rule_packages/c/Declarations1.json | 3 ++- rule_packages/c/Declarations3.json | 25 +++++++++++++++++++ rules.csv | 2 +- 14 files changed, 110 insertions(+), 17 deletions(-) delete mode 100644 c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.qlref create mode 100644 c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.testref rename c/{cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected => common/test/rules/typeomitted/TypeOmitted.expected} (100%) create mode 100644 c/common/test/rules/typeomitted/TypeOmitted.ql rename c/{cert/test/rules/DCL31-C => common/test/rules/typeomitted}/test.c (58%) create mode 100644 c/misra/src/rules/RULE-8-1/ExplicitlyDeclareTypes.ql create mode 100644 c/misra/test/rules/RULE-8-1/ExplicitlyDeclareTypes.testref create mode 100644 cpp/common/src/codingstandards/cpp/rules/typeomitted/TypeOmitted.qll diff --git a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md index 677e3fcb03..0acf9d200a 100644 --- a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md +++ b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.md @@ -153,7 +153,7 @@ Search for [vulnerabilities](https://wiki.sei.cmu.edu/confluence/display/c/BB.+D ## Implementation notes -This query does not check for implicit function declarations as this is partially compiler checked. +This query does not check for implicitly typed parameters, typedefs or member declarations as this is partially compiler checked. ## References diff --git a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql index 0d2e241957..369baa4a63 100644 --- a/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql +++ b/c/cert/src/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql @@ -13,16 +13,10 @@ import cpp import codingstandards.c.cert +import codingstandards.cpp.rules.typeomitted.TypeOmitted -from Declaration d -where - not isExcluded(d, Declarations1Package::declareIdentifiersBeforeUsingThemQuery()) and - 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 " + d.getName() + " is missing a type specifier." +class DeclareIdentifiersBeforeUsingThem extends TypeOmittedSharedQuery { + DeclareIdentifiersBeforeUsingThem() { + this = Declarations1Package::declareIdentifiersBeforeUsingThemQuery() + } +} diff --git a/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.qlref b/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.qlref deleted file mode 100644 index f51571a4fe..0000000000 --- a/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.ql \ No newline at end of file diff --git a/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.testref b/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.testref new file mode 100644 index 0000000000..613692096f --- /dev/null +++ b/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.testref @@ -0,0 +1 @@ +c/common/test/rules/typeomitted/TypeOmitted.ql \ No newline at end of file diff --git a/c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected b/c/common/test/rules/typeomitted/TypeOmitted.expected similarity index 100% rename from c/cert/test/rules/DCL31-C/DeclareIdentifiersBeforeUsingThem.expected rename to c/common/test/rules/typeomitted/TypeOmitted.expected diff --git a/c/common/test/rules/typeomitted/TypeOmitted.ql b/c/common/test/rules/typeomitted/TypeOmitted.ql new file mode 100644 index 0000000000..d0853e90a4 --- /dev/null +++ b/c/common/test/rules/typeomitted/TypeOmitted.ql @@ -0,0 +1,2 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.typeomitted.TypeOmitted diff --git a/c/cert/test/rules/DCL31-C/test.c b/c/common/test/rules/typeomitted/test.c similarity index 58% rename from c/cert/test/rules/DCL31-C/test.c rename to c/common/test/rules/typeomitted/test.c index 7442adb246..db854da269 100644 --- a/c/cert/test/rules/DCL31-C/test.c +++ b/c/common/test/rules/typeomitted/test.c @@ -13,3 +13,13 @@ int f1(void) { // COMPLIANT short g2; // COMPLIANT long g3; // COMPLIANT signed g4() { return 1; } // COMPLIANT + +typedef *newtype3; // NON_COMPLIANT[FALSE_NEGATIVE] + +int f2(const x) { // NON_COMPLIANT[FALSE_NEGATIVE] + return 1; +} + +struct str { + const y; // NON_COMPLIANT[FALSE_NEGATIVE] +} s; diff --git a/c/misra/src/rules/RULE-8-1/ExplicitlyDeclareTypes.ql b/c/misra/src/rules/RULE-8-1/ExplicitlyDeclareTypes.ql new file mode 100644 index 0000000000..bfcbac4435 --- /dev/null +++ b/c/misra/src/rules/RULE-8-1/ExplicitlyDeclareTypes.ql @@ -0,0 +1,20 @@ +/** + * @id c/misra/explicitly-declare-types + * @name RULE-8-1: 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/misra/id/rule-8-1 + * correctness + * readability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.cpp.rules.typeomitted.TypeOmitted + +class ExplicitlyDeclareTypesQuery extends TypeOmittedSharedQuery { + ExplicitlyDeclareTypesQuery() { this = Declarations3Package::explicitlyDeclareTypesQuery() } +} diff --git a/c/misra/test/rules/RULE-8-1/ExplicitlyDeclareTypes.testref b/c/misra/test/rules/RULE-8-1/ExplicitlyDeclareTypes.testref new file mode 100644 index 0000000000..613692096f --- /dev/null +++ b/c/misra/test/rules/RULE-8-1/ExplicitlyDeclareTypes.testref @@ -0,0 +1 @@ +c/common/test/rules/typeomitted/TypeOmitted.ql \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll index d31011234a..0aa63e6dc5 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations3.qll @@ -7,7 +7,8 @@ newtype Declarations3Query = TIdentifierHidingCQuery() or TIdentifiersNotDistinctFromMacroNamesQuery() or TTypedefNameNotUniqueQuery() or - TTagNameNotUniqueQuery() + TTagNameNotUniqueQuery() or + TExplicitlyDeclareTypesQuery() predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleId) { query = @@ -41,6 +42,14 @@ predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleI // `@id` for the `tagNameNotUnique` query "c/misra/tag-name-not-unique" and ruleId = "RULE-5-7" + or + query = + // `Query` instance for the `explicitlyDeclareTypes` query + Declarations3Package::explicitlyDeclareTypesQuery() and + queryId = + // `@id` for the `explicitlyDeclareTypes` query + "c/misra/explicitly-declare-types" and + ruleId = "RULE-8-1" } module Declarations3Package { @@ -71,4 +80,11 @@ module Declarations3Package { // `Query` type for `tagNameNotUnique` query TQueryC(TDeclarations3PackageQuery(TTagNameNotUniqueQuery())) } + + Query explicitlyDeclareTypesQuery() { + //autogenerate `Query` type + result = + // `Query` type for `explicitlyDeclareTypes` query + TQueryC(TDeclarations3PackageQuery(TExplicitlyDeclareTypesQuery())) + } } diff --git a/cpp/common/src/codingstandards/cpp/rules/typeomitted/TypeOmitted.qll b/cpp/common/src/codingstandards/cpp/rules/typeomitted/TypeOmitted.qll new file mode 100644 index 0000000000..420a384208 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/rules/typeomitted/TypeOmitted.qll @@ -0,0 +1,24 @@ +/** + * Provides a library which includes a `problems` predicate for reporting.... + */ + +import cpp +import codingstandards.cpp.Customizations +import codingstandards.cpp.Exclusions + +abstract class TypeOmittedSharedQuery extends Query { } + +Query getQuery() { result instanceof TypeOmittedSharedQuery } + +query predicate problems(Declaration d, string message) { + not isExcluded(d, getQuery()) and + 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()) + ) and + message = "Declaration " + d.getName() + " is missing a type specifier." +} diff --git a/rule_packages/c/Declarations1.json b/rule_packages/c/Declarations1.json index 417d6f1f84..217e1e077c 100644 --- a/rule_packages/c/Declarations1.json +++ b/rule_packages/c/Declarations1.json @@ -12,12 +12,13 @@ "precision": "very-high", "severity": "error", "short_name": "DeclareIdentifiersBeforeUsingThem", + "shared_implementation_short_name": "TypeOmitted", "tags": [ "correctness", "readability" ], "implementation_scope": { - "description": "This query does not check for implicit function declarations as this is partially compiler checked.", + "description": "This query does not check for implicitly typed parameters, typedefs or member declarations as this is partially compiler checked.", "items": [] } } diff --git a/rule_packages/c/Declarations3.json b/rule_packages/c/Declarations3.json index b6307c71cb..a22567b237 100644 --- a/rule_packages/c/Declarations3.json +++ b/rule_packages/c/Declarations3.json @@ -83,6 +83,31 @@ } ], "title": "A tag name shall be a unique identifier" + }, + "RULE-8-1": { + "properties": { + "obligation": "required" + }, + "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": "ExplicitlyDeclareTypes", + "shared_implementation_short_name": "TypeOmitted", + "tags": [ + "correctness", + "readability" + ], + "implementation_scope": { + "description": "This query does not check for implicitly typed parameters, typedefs or member declarations as this is partially compiler checked.", + "items": [] + } + } + ], + "title": "Types shall be explicitly specified" } } } \ No newline at end of file diff --git a/rules.csv b/rules.csv index aa0f3f5245..ab39a0d0f5 100755 --- a/rules.csv +++ b/rules.csv @@ -646,7 +646,7 @@ c,MISRA-C-2012,RULE-7-1,Yes,Required,,,Octal constants shall not be used,M2-13-2 c,MISRA-C-2012,RULE-7-2,Yes,Required,,,A �u� or �U� suffix shall be applied to all integer constants that are represented in an unsigned type,M2-13-3,Syntax,Easy, c,MISRA-C-2012,RULE-7-3,Yes,Required,,,The lowercase character �l� shall not be used in a literal suffix,M2-13-4,Syntax,Easy, c,MISRA-C-2012,RULE-7-4,Yes,Required,,,A string literal shall not be assigned to an object unless the object�s type is �pointer to const-qualified char�,A2-13-4,Types,Easy, -c,MISRA-C-2012,RULE-8-1,Yes,Required,,,Types shall be explicitly specified,,Declarations,Medium, +c,MISRA-C-2012,RULE-8-1,Yes,Required,,,Types shall be explicitly specified,,Declarations3,Medium, c,MISRA-C-2012,RULE-8-2,Yes,Required,,,Function types shall be in prototype form with named parameters,,Declarations,Medium, c,MISRA-C-2012,RULE-8-3,Yes,Required,,,All declarations of an object or function shall use the same names and type qualifiers,M3-2-1,Declarations,Medium, c,MISRA-C-2012,RULE-8-4,Yes,Required,,,A compatible declaration shall be visible when an object or function with external linkage is defined,,Declarations,Medium,