diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Undefined.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Undefined.qll index 37ae63fa5..ce5fedd5c 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Undefined.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Undefined.qll @@ -8,7 +8,10 @@ newtype UndefinedQuery = TCriticalUnspecifiedBehaviorQuery() or TUndefinedBehaviorAuditQuery() or TCriticalUnspecifiedBehaviorAuditQuery() or - TPossibleDataRaceBetweenThreadsQuery() + TPossibleDataRaceBetweenThreadsQuery() or + TNullPointerToMemberAccessUndefinedBehaviorQuery() or + TUninitializedStaticPointerToMemberUndefinedBehaviorQuery() or + TNonExistentMemberAccessUndefinedBehaviorQuery() predicate isUndefinedQueryMetadata(Query query, string queryId, string ruleId, string category) { query = @@ -55,6 +58,33 @@ predicate isUndefinedQueryMetadata(Query query, string queryId, string ruleId, s "cpp/misra/possible-data-race-between-threads" and ruleId = "RULE-4-1-3" and category = "required" + or + query = + // `Query` instance for the `nullPointerToMemberAccessUndefinedBehavior` query + UndefinedPackage::nullPointerToMemberAccessUndefinedBehaviorQuery() and + queryId = + // `@id` for the `nullPointerToMemberAccessUndefinedBehavior` query + "cpp/misra/null-pointer-to-member-access-undefined-behavior" and + ruleId = "RULE-4-1-3" and + category = "required" + or + query = + // `Query` instance for the `uninitializedStaticPointerToMemberUndefinedBehavior` query + UndefinedPackage::uninitializedStaticPointerToMemberUndefinedBehaviorQuery() and + queryId = + // `@id` for the `uninitializedStaticPointerToMemberUndefinedBehavior` query + "cpp/misra/uninitialized-static-pointer-to-member-undefined-behavior" and + ruleId = "RULE-4-1-3" and + category = "required" + or + query = + // `Query` instance for the `nonExistentMemberAccessUndefinedBehavior` query + UndefinedPackage::nonExistentMemberAccessUndefinedBehaviorQuery() and + queryId = + // `@id` for the `nonExistentMemberAccessUndefinedBehavior` query + "cpp/misra/non-existent-member-access-undefined-behavior" and + ruleId = "RULE-4-1-3" and + category = "required" } module UndefinedPackage { @@ -92,4 +122,25 @@ module UndefinedPackage { // `Query` type for `possibleDataRaceBetweenThreads` query TQueryCPP(TUndefinedPackageQuery(TPossibleDataRaceBetweenThreadsQuery())) } + + Query nullPointerToMemberAccessUndefinedBehaviorQuery() { + //autogenerate `Query` type + result = + // `Query` type for `nullPointerToMemberAccessUndefinedBehavior` query + TQueryCPP(TUndefinedPackageQuery(TNullPointerToMemberAccessUndefinedBehaviorQuery())) + } + + Query uninitializedStaticPointerToMemberUndefinedBehaviorQuery() { + //autogenerate `Query` type + result = + // `Query` type for `uninitializedStaticPointerToMemberUndefinedBehavior` query + TQueryCPP(TUndefinedPackageQuery(TUninitializedStaticPointerToMemberUndefinedBehaviorQuery())) + } + + Query nonExistentMemberAccessUndefinedBehaviorQuery() { + //autogenerate `Query` type + result = + // `Query` type for `nonExistentMemberAccessUndefinedBehavior` query + TQueryCPP(TUndefinedPackageQuery(TNonExistentMemberAccessUndefinedBehaviorQuery())) + } } diff --git a/cpp/misra/src/rules/RULE-4-1-3/NonExistentMemberAccessUndefinedBehavior.ql b/cpp/misra/src/rules/RULE-4-1-3/NonExistentMemberAccessUndefinedBehavior.ql new file mode 100644 index 000000000..36ee4070d --- /dev/null +++ b/cpp/misra/src/rules/RULE-4-1-3/NonExistentMemberAccessUndefinedBehavior.ql @@ -0,0 +1,26 @@ +/** + * @id cpp/misra/non-existent-member-access-undefined-behavior + * @name RULE-4-1-3: Pointer-to-member access of nonexistent member leads to undefined behavior + * @description Using a pointer-to-member expression where the dynamic type of the first operand + * does not contain the member pointed to by the second operand results in undefined + * behavior. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-4-1-3 + * correctness + * scope/system + * external/misra/enforcement/undecidable + * external/misra/obligation/required + */ + +import cpp +import codingstandards.cpp.misra +import codingstandards.cpp.rules.accessofnonexistingmemberthroughpointertomember.AccessOfNonExistingMemberThroughPointerToMember + +class NonExistentMemberAccessUndefinedBehaviorQuery extends AccessOfNonExistingMemberThroughPointerToMemberSharedQuery +{ + NonExistentMemberAccessUndefinedBehaviorQuery() { + this = UndefinedPackage::nonExistentMemberAccessUndefinedBehaviorQuery() + } +} diff --git a/cpp/misra/src/rules/RULE-4-1-3/NullPointerToMemberAccessUndefinedBehavior.ql b/cpp/misra/src/rules/RULE-4-1-3/NullPointerToMemberAccessUndefinedBehavior.ql new file mode 100644 index 000000000..87dcba4dd --- /dev/null +++ b/cpp/misra/src/rules/RULE-4-1-3/NullPointerToMemberAccessUndefinedBehavior.ql @@ -0,0 +1,25 @@ +/** + * @id cpp/misra/null-pointer-to-member-access-undefined-behavior + * @name RULE-4-1-3: Null pointer-to-member access leads to undefined behavior + * @description Using a null pointer-to-member value as the second operand in a pointer-to-member + * expression results in undefined behavior. + * @kind path-problem + * @precision high + * @problem.severity error + * @tags external/misra/id/rule-4-1-3 + * correctness + * scope/system + * external/misra/enforcement/undecidable + * external/misra/obligation/required + */ + +import cpp +import codingstandards.cpp.misra +import codingstandards.cpp.rules.accessofundefinedmemberthroughnullpointer.AccessOfUndefinedMemberThroughNullPointer + +class NullPointerToMemberAccessUndefinedBehaviorQuery extends AccessOfUndefinedMemberThroughNullPointerSharedQuery +{ + NullPointerToMemberAccessUndefinedBehaviorQuery() { + this = UndefinedPackage::nullPointerToMemberAccessUndefinedBehaviorQuery() + } +} diff --git a/cpp/misra/src/rules/RULE-4-1-3/UninitializedStaticPointerToMemberUndefinedBehavior.ql b/cpp/misra/src/rules/RULE-4-1-3/UninitializedStaticPointerToMemberUndefinedBehavior.ql new file mode 100644 index 000000000..331a05a84 --- /dev/null +++ b/cpp/misra/src/rules/RULE-4-1-3/UninitializedStaticPointerToMemberUndefinedBehavior.ql @@ -0,0 +1,25 @@ +/** + * @id cpp/misra/uninitialized-static-pointer-to-member-undefined-behavior + * @name RULE-4-1-3: Uninitialized static pointer-to-member access leads to undefined behavior + * @description Using an uninitialized static pointer-to-member in a pointer-to-member expression + * results in undefined behavior. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-4-1-3 + * correctness + * scope/system + * external/misra/enforcement/undecidable + * external/misra/obligation/required + */ + +import cpp +import codingstandards.cpp.misra +import codingstandards.cpp.rules.accessofundefinedmemberthroughuninitializedstaticpointer.AccessOfUndefinedMemberThroughUninitializedStaticPointer + +class UninitializedStaticPointerToMemberUndefinedBehaviorQuery extends AccessOfUndefinedMemberThroughUninitializedStaticPointerSharedQuery +{ + UninitializedStaticPointerToMemberUndefinedBehaviorQuery() { + this = UndefinedPackage::uninitializedStaticPointerToMemberUndefinedBehaviorQuery() + } +} diff --git a/cpp/misra/test/rules/RULE-4-1-3/NonExistentMemberAccessUndefinedBehavior.testref b/cpp/misra/test/rules/RULE-4-1-3/NonExistentMemberAccessUndefinedBehavior.testref new file mode 100644 index 000000000..cc80a25a0 --- /dev/null +++ b/cpp/misra/test/rules/RULE-4-1-3/NonExistentMemberAccessUndefinedBehavior.testref @@ -0,0 +1 @@ +cpp/common/test/rules/accessofnonexistingmemberthroughpointertomember/AccessOfNonExistingMemberThroughPointerToMember.ql diff --git a/cpp/misra/test/rules/RULE-4-1-3/NullPointerToMemberAccessUndefinedBehavior.testref b/cpp/misra/test/rules/RULE-4-1-3/NullPointerToMemberAccessUndefinedBehavior.testref new file mode 100644 index 000000000..717d30ef7 --- /dev/null +++ b/cpp/misra/test/rules/RULE-4-1-3/NullPointerToMemberAccessUndefinedBehavior.testref @@ -0,0 +1 @@ +cpp/common/test/rules/accessofundefinedmemberthroughnullpointer/AccessOfUndefinedMemberThroughNullPointer.ql diff --git a/cpp/misra/test/rules/RULE-4-1-3/UninitializedStaticPointerToMemberUndefinedBehavior.testref b/cpp/misra/test/rules/RULE-4-1-3/UninitializedStaticPointerToMemberUndefinedBehavior.testref new file mode 100644 index 000000000..903178895 --- /dev/null +++ b/cpp/misra/test/rules/RULE-4-1-3/UninitializedStaticPointerToMemberUndefinedBehavior.testref @@ -0,0 +1 @@ +cpp/common/test/rules/accessofundefinedmemberthroughuninitializedstaticpointer/AccessOfUndefinedMemberThroughUninitializedStaticPointer.ql diff --git a/rule_packages/cpp/Undefined.json b/rule_packages/cpp/Undefined.json index bc0b10af3..4c89a3b20 100644 --- a/rule_packages/cpp/Undefined.json +++ b/rule_packages/cpp/Undefined.json @@ -69,6 +69,45 @@ "concurrency", "scope/system" ] + }, + { + "description": "Using a null pointer-to-member value as the second operand in a pointer-to-member expression results in undefined behavior.", + "kind": "path-problem", + "name": "Null pointer-to-member access leads to undefined behavior", + "precision": "high", + "severity": "error", + "shared_implementation_short_name": "AccessOfUndefinedMemberThroughNullPointer", + "short_name": "NullPointerToMemberAccessUndefinedBehavior", + "tags": [ + "correctness", + "scope/system" + ] + }, + { + "description": "Using an uninitialized static pointer-to-member in a pointer-to-member expression results in undefined behavior.", + "kind": "problem", + "name": "Uninitialized static pointer-to-member access leads to undefined behavior", + "precision": "very-high", + "severity": "error", + "shared_implementation_short_name": "AccessOfUndefinedMemberThroughUninitializedStaticPointer", + "short_name": "UninitializedStaticPointerToMemberUndefinedBehavior", + "tags": [ + "correctness", + "scope/system" + ] + }, + { + "description": "Using a pointer-to-member expression where the dynamic type of the first operand does not contain the member pointed to by the second operand results in undefined behavior.", + "kind": "problem", + "name": "Pointer-to-member access of nonexistent member leads to undefined behavior", + "precision": "very-high", + "severity": "error", + "shared_implementation_short_name": "AccessOfNonExistingMemberThroughPointerToMember", + "short_name": "NonExistentMemberAccessUndefinedBehavior", + "tags": [ + "correctness", + "scope/system" + ] } ], "title": "There shall be no occurrence of undefined or critical unspecified behaviour"