From 12370bc599deeb7bc406bd890d6edb7159e1620f Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 20 Sep 2024 11:17:13 -0700 Subject: [PATCH 1/3] Add support for MISRA-C Rule 6.3 --- .../BitFieldDeclaredAsMemberOfAUnion.ql | 22 ++++++++++++++++ .../BitFieldDeclaredAsMemberOfAUnion.expected | 2 ++ .../BitFieldDeclaredAsMemberOfAUnion.qlref | 1 + c/misra/test/rules/RULE-6-3/test.c | 21 +++++++++++++++ .../cpp/exclusions/c/BitfieldTypes2.qll | 26 +++++++++++++++++++ .../cpp/exclusions/c/RuleMetadata.qll | 3 +++ rule_packages/c/BitfieldTypes2.json | 21 +++++++++++++++ 7 files changed, 96 insertions(+) create mode 100644 c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql create mode 100644 c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.expected create mode 100644 c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.qlref create mode 100644 c/misra/test/rules/RULE-6-3/test.c create mode 100644 cpp/common/src/codingstandards/cpp/exclusions/c/BitfieldTypes2.qll create mode 100644 rule_packages/c/BitfieldTypes2.json diff --git a/c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql b/c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql new file mode 100644 index 0000000000..c91f25da10 --- /dev/null +++ b/c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql @@ -0,0 +1,22 @@ +/** + * @id c/misra/bit-field-declared-as-member-of-a-union + * @name RULE-6-3: A bit field shall not be declared as a member of a union + * @description Type punning on a union with bit fields relies on implementation-specific alignment + * behavior. + * @kind problem + * @precision very-high + * @problem.severity warning + * @tags external/misra/id/rule-6-3 + * correctness + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra + +from BitField field, Union u +where + not isExcluded(field, BitfieldTypes2Package::bitFieldDeclaredAsMemberOfAUnionQuery()) and + u.getAField() = field +select + field, "Union member " + field.getName() + " is declared as a bit field which relies on implementation-specific behavior." \ No newline at end of file diff --git a/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.expected b/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.expected new file mode 100644 index 0000000000..7c39484796 --- /dev/null +++ b/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.expected @@ -0,0 +1,2 @@ +| test.c:7:7:7:7 | x | Union member x is declared as a bit field which relies on implementation-specific behavior. | +| test.c:20:7:20:7 | (unnamed bitfield) | Union member (unnamed bitfield) is declared as a bit field which relies on implementation-specific behavior. | diff --git a/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.qlref b/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.qlref new file mode 100644 index 0000000000..21c43d4826 --- /dev/null +++ b/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.qlref @@ -0,0 +1 @@ +rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-6-3/test.c b/c/misra/test/rules/RULE-6-3/test.c new file mode 100644 index 0000000000..74b7cb86ea --- /dev/null +++ b/c/misra/test/rules/RULE-6-3/test.c @@ -0,0 +1,21 @@ +union U1 { + int x; // COMPLIANT + char y; // COMPLIANT +}; + +union U2 { + int x: 2; // NON-COMPLIANT + char y; // COMPLIANT +}; + +union U3 { + struct str { + int x: 4; // COMPLIANT + int y: 2; // COMPLIANT + }; +}; + +union U4 { + char x; + int :0; // NON-COMPLIANT +}; \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/BitfieldTypes2.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/BitfieldTypes2.qll new file mode 100644 index 0000000000..ca116bb51c --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/BitfieldTypes2.qll @@ -0,0 +1,26 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype BitfieldTypes2Query = TBitFieldDeclaredAsMemberOfAUnionQuery() + +predicate isBitfieldTypes2QueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `bitFieldDeclaredAsMemberOfAUnion` query + BitfieldTypes2Package::bitFieldDeclaredAsMemberOfAUnionQuery() and + queryId = + // `@id` for the `bitFieldDeclaredAsMemberOfAUnion` query + "c/misra/bit-field-declared-as-member-of-a-union" and + ruleId = "RULE-6-3" and + category = "required" +} + +module BitfieldTypes2Package { + Query bitFieldDeclaredAsMemberOfAUnionQuery() { + //autogenerate `Query` type + result = + // `Query` type for `bitFieldDeclaredAsMemberOfAUnion` query + TQueryC(TBitfieldTypes2PackageQuery(TBitFieldDeclaredAsMemberOfAUnionQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll index c2771f4171..2ddc5138b8 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll @@ -4,6 +4,7 @@ import codingstandards.cpp.exclusions.RuleMetadata //** Import packages for this language **/ import Banned import BitfieldTypes +import BitfieldTypes2 import Concurrency1 import Concurrency2 import Concurrency3 @@ -75,6 +76,7 @@ import Types1 newtype TCQuery = TBannedPackageQuery(BannedQuery q) or TBitfieldTypesPackageQuery(BitfieldTypesQuery q) or + TBitfieldTypes2PackageQuery(BitfieldTypes2Query q) or TConcurrency1PackageQuery(Concurrency1Query q) or TConcurrency2PackageQuery(Concurrency2Query q) or TConcurrency3PackageQuery(Concurrency3Query q) or @@ -146,6 +148,7 @@ newtype TCQuery = predicate isQueryMetadata(Query query, string queryId, string ruleId, string category) { isBannedQueryMetadata(query, queryId, ruleId, category) or isBitfieldTypesQueryMetadata(query, queryId, ruleId, category) or + isBitfieldTypes2QueryMetadata(query, queryId, ruleId, category) or isConcurrency1QueryMetadata(query, queryId, ruleId, category) or isConcurrency2QueryMetadata(query, queryId, ruleId, category) or isConcurrency3QueryMetadata(query, queryId, ruleId, category) or diff --git a/rule_packages/c/BitfieldTypes2.json b/rule_packages/c/BitfieldTypes2.json new file mode 100644 index 0000000000..d916421b1f --- /dev/null +++ b/rule_packages/c/BitfieldTypes2.json @@ -0,0 +1,21 @@ +{ + "MISRA-C-2012": { + "RULE-6-3": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "Type punning on a union with bit fields relies on implementation-specific alignment behavior.", + "kind": "problem", + "name": "A bit field shall not be declared as a member of a union", + "precision": "very-high", + "severity": "warning", + "short_name": "BitFieldDeclaredAsMemberOfAUnion", + "tags": ["correctness"] + } + ], + "title": "A bit field shall not be declared as a member of a union" + } + } +} \ No newline at end of file From 9c0e6baa1ef4a6d890662bf7c18dcdb523fac63a Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 20 Sep 2024 11:28:02 -0700 Subject: [PATCH 2/3] clang format --- c/misra/test/rules/RULE-6-3/test.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/c/misra/test/rules/RULE-6-3/test.c b/c/misra/test/rules/RULE-6-3/test.c index 74b7cb86ea..1de648d294 100644 --- a/c/misra/test/rules/RULE-6-3/test.c +++ b/c/misra/test/rules/RULE-6-3/test.c @@ -1,21 +1,21 @@ union U1 { - int x; // COMPLIANT + int x; // COMPLIANT char y; // COMPLIANT }; union U2 { - int x: 2; // NON-COMPLIANT - char y; // COMPLIANT + int x : 2; // NON-COMPLIANT + char y; // COMPLIANT }; union U3 { - struct str { - int x: 4; // COMPLIANT - int y: 2; // COMPLIANT - }; + struct str { + int x : 4; // COMPLIANT + int y : 2; // COMPLIANT + }; }; union U4 { char x; - int :0; // NON-COMPLIANT + int : 0; // NON-COMPLIANT }; \ No newline at end of file From ba844d1698b99247842f830dfbfa871f46d1fa98 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 20 Sep 2024 11:35:20 -0700 Subject: [PATCH 3/3] Format codeql query --- .../src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql b/c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql index c91f25da10..5fcf938046 100644 --- a/c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql +++ b/c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql @@ -18,5 +18,6 @@ from BitField field, Union u where not isExcluded(field, BitfieldTypes2Package::bitFieldDeclaredAsMemberOfAUnionQuery()) and u.getAField() = field -select - field, "Union member " + field.getName() + " is declared as a bit field which relies on implementation-specific behavior." \ No newline at end of file +select field, + "Union member " + field.getName() + + " is declared as a bit field which relies on implementation-specific behavior."