diff --git a/c/misra/src/rules/RULE-11-10/AtomicQualifierAppliedToVoid.ql b/c/misra/src/rules/RULE-11-10/AtomicQualifierAppliedToVoid.ql new file mode 100644 index 0000000000..d867241518 --- /dev/null +++ b/c/misra/src/rules/RULE-11-10/AtomicQualifierAppliedToVoid.ql @@ -0,0 +1,36 @@ +/** + * @id c/misra/atomic-qualifier-applied-to-void + * @name RULE-11-10: The _Atomic qualifier shall not be applied to the incomplete type void + * @description Conversions between types by using an _Atomic void type may result in undefined + * behavior. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-11-10 + * correctness + * external/misra/c/2012/third-edition-first-revision + * external/misra/c/2012/amendment4 + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra + +class AtomicVoidType extends Type { + AtomicVoidType() { + hasSpecifier("atomic") and + getUnspecifiedType() instanceof VoidType + } +} + +Type getNestedType(Type root) { + result = root + or + exists(DerivedType derived | derived = root | result = getNestedType(derived.getBaseType())) +} + +from DeclarationEntry decl, AtomicVoidType atomicVoid +where + not isExcluded(decl, Declarations9Package::atomicQualifierAppliedToVoidQuery()) and + atomicVoid = getNestedType(decl.getType()) +select decl, decl.getName() + " declared with an atomic void type." diff --git a/c/misra/test/rules/RULE-11-10/AtomicQualifierAppliedToVoid.expected b/c/misra/test/rules/RULE-11-10/AtomicQualifierAppliedToVoid.expected new file mode 100644 index 0000000000..e3a6746ae7 --- /dev/null +++ b/c/misra/test/rules/RULE-11-10/AtomicQualifierAppliedToVoid.expected @@ -0,0 +1,3 @@ +| test.c:3:15:3:16 | definition of g3 | g3 declared with an atomic void type. | +| test.c:10:17:10:18 | definition of m3 | m3 declared with an atomic void type. | +| test.c:15:22:15:23 | definition of p2 | p2 declared with an atomic void type. | diff --git a/c/misra/test/rules/RULE-11-10/AtomicQualifierAppliedToVoid.qlref b/c/misra/test/rules/RULE-11-10/AtomicQualifierAppliedToVoid.qlref new file mode 100644 index 0000000000..2046575237 --- /dev/null +++ b/c/misra/test/rules/RULE-11-10/AtomicQualifierAppliedToVoid.qlref @@ -0,0 +1 @@ +rules/RULE-11-10/AtomicQualifierAppliedToVoid.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-11-10/test.c b/c/misra/test/rules/RULE-11-10/test.c new file mode 100644 index 0000000000..e030345dde --- /dev/null +++ b/c/misra/test/rules/RULE-11-10/test.c @@ -0,0 +1,18 @@ +// _Atomic void g1; // doesn't compile +_Atomic int g2; // COMPLIANT +_Atomic void *g3; // NON_COMPLIANT +// _Atomic void g4[]; // doesn't compile +void *_Atomic g5; // COMPLIANT + +struct { + _Atomic int m1; // COMPLIANT + // _Atomic void m2; // doesn't compile + _Atomic void *m3; // NON_COMPLIANT + void *_Atomic m4; // COMPLIANT +} s1; + +void f(_Atomic int p1, // COMPLIANT + _Atomic void *p2 // NON_COMPLIANT + // _Atomic void p3[] // doesn't compile, even though it perhaps should as + // it is adjusted to void*. +) {} \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations9.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations9.qll new file mode 100644 index 0000000000..8a63e50ed4 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Declarations9.qll @@ -0,0 +1,26 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Declarations9Query = TAtomicQualifierAppliedToVoidQuery() + +predicate isDeclarations9QueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `atomicQualifierAppliedToVoid` query + Declarations9Package::atomicQualifierAppliedToVoidQuery() and + queryId = + // `@id` for the `atomicQualifierAppliedToVoid` query + "c/misra/atomic-qualifier-applied-to-void" and + ruleId = "RULE-11-10" and + category = "required" +} + +module Declarations9Package { + Query atomicQualifierAppliedToVoidQuery() { + //autogenerate `Query` type + result = + // `Query` type for `atomicQualifierAppliedToVoid` query + TQueryC(TDeclarations9PackageQuery(TAtomicQualifierAppliedToVoidQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll index 1562ba7894..448b764526 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll @@ -28,6 +28,7 @@ import Declarations5 import Declarations6 import Declarations7 import Declarations8 +import Declarations9 import EssentialTypes import Expressions import FloatingTypes @@ -107,6 +108,7 @@ newtype TCQuery = TDeclarations6PackageQuery(Declarations6Query q) or TDeclarations7PackageQuery(Declarations7Query q) or TDeclarations8PackageQuery(Declarations8Query q) or + TDeclarations9PackageQuery(Declarations9Query q) or TEssentialTypesPackageQuery(EssentialTypesQuery q) or TExpressionsPackageQuery(ExpressionsQuery q) or TFloatingTypesPackageQuery(FloatingTypesQuery q) or @@ -186,6 +188,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat isDeclarations6QueryMetadata(query, queryId, ruleId, category) or isDeclarations7QueryMetadata(query, queryId, ruleId, category) or isDeclarations8QueryMetadata(query, queryId, ruleId, category) or + isDeclarations9QueryMetadata(query, queryId, ruleId, category) or isEssentialTypesQueryMetadata(query, queryId, ruleId, category) or isExpressionsQueryMetadata(query, queryId, ruleId, category) or isFloatingTypesQueryMetadata(query, queryId, ruleId, category) or diff --git a/rule_packages/c/Declarations9.json b/rule_packages/c/Declarations9.json new file mode 100644 index 0000000000..ebfcf7c41f --- /dev/null +++ b/rule_packages/c/Declarations9.json @@ -0,0 +1,25 @@ +{ + "MISRA-C-2012": { + "RULE-11-10": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "Conversions between types by using an _Atomic void type may result in undefined behavior.", + "kind": "problem", + "name": "The _Atomic qualifier shall not be applied to the incomplete type void", + "precision": "very-high", + "severity": "error", + "short_name": "AtomicQualifierAppliedToVoid", + "tags": [ + "correctness", + "external/misra/c/2012/third-edition-first-revision", + "external/misra/c/2012/amendment4" + ] + } + ], + "title": "The _Atomic qualifier shall not be applied to the incomplete type void" + } + } +} \ No newline at end of file diff --git a/rules.csv b/rules.csv index 475ea1d66c..6657055cad 100644 --- a/rules.csv +++ b/rules.csv @@ -677,7 +677,7 @@ c,MISRA-C-2012,RULE-9-2,Yes,Required,,,The initializer for an aggregate or union c,MISRA-C-2012,RULE-9-3,Yes,Required,,,Arrays shall not be partially initialized,,Memory1,Medium, c,MISRA-C-2012,RULE-9-4,Yes,Required,,,An element of an object shall not be initialized more than once,,Memory1,Medium, c,MISRA-C-2012,RULE-9-5,No,Required,,,Where designated initializers are used to initialize an array object the size of the array shall be specified explicitly,,,Medium, -c,MISRA-C-2012,RULE-9-6,Yes,Required,,,An initializer using chained designators shall not contain initializers without designators,,Declarations9,Hard, +c,MISRA-C-2012,RULE-9-6,Yes,Required,,,An initializer using chained designators shall not contain initializers without designators,,Declarations10,Hard, c,MISRA-C-2012,RULE-9-7,Yes,Mandatory,,,Atomic objects shall be appropriately initialized before being accessed,,Concurrency6,Hard, c,MISRA-C-2012,RULE-10-1,Yes,Required,,,Operands shall not be of an inappropriate essential type,,EssentialTypes,Hard, c,MISRA-C-2012,RULE-10-2,Yes,Required,,,Expressions of essentially character type shall not be used inappropriately in addition and subtraction operations,,EssentialTypes,Medium,