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..5fcf938046 --- /dev/null +++ b/c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql @@ -0,0 +1,23 @@ +/** + * @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." 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..1de648d294 --- /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