Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
import cpp
import RuleMetadata
import codingstandards.cpp.exclusions.RuleMetadata

newtype Preconditions1Query = TPolymorphicClassTypeExpressionInTypeidQuery()

predicate isPreconditions1QueryMetadata(Query query, string queryId, string ruleId, string category) {
query =
// `Query` instance for the `polymorphicClassTypeExpressionInTypeid` query
Preconditions1Package::polymorphicClassTypeExpressionInTypeidQuery() and
queryId =
// `@id` for the `polymorphicClassTypeExpressionInTypeid` query
"cpp/misra/polymorphic-class-type-expression-in-typeid" and
ruleId = "RULE-8-2-9" and
category = "required"
}

module Preconditions1Package {
Query polymorphicClassTypeExpressionInTypeidQuery() {
//autogenerate `Query` type
result =
// `Query` type for `polymorphicClassTypeExpressionInTypeid` query
TQueryCPP(TPreconditions1PackageQuery(TPolymorphicClassTypeExpressionInTypeidQuery()))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import Operators
import OrderOfEvaluation
import OutOfBounds
import Pointers
import Preconditions1
import Representation
import Scope
import SideEffects1
Expand Down Expand Up @@ -103,6 +104,7 @@ newtype TCPPQuery =
TOrderOfEvaluationPackageQuery(OrderOfEvaluationQuery q) or
TOutOfBoundsPackageQuery(OutOfBoundsQuery q) or
TPointersPackageQuery(PointersQuery q) or
TPreconditions1PackageQuery(Preconditions1Query q) or
TRepresentationPackageQuery(RepresentationQuery q) or
TScopePackageQuery(ScopeQuery q) or
TSideEffects1PackageQuery(SideEffects1Query q) or
Expand Down Expand Up @@ -162,6 +164,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
isOrderOfEvaluationQueryMetadata(query, queryId, ruleId, category) or
isOutOfBoundsQueryMetadata(query, queryId, ruleId, category) or
isPointersQueryMetadata(query, queryId, ruleId, category) or
isPreconditions1QueryMetadata(query, queryId, ruleId, category) or
isRepresentationQueryMetadata(query, queryId, ruleId, category) or
isScopeQueryMetadata(query, queryId, ruleId, category) or
isSideEffects1QueryMetadata(query, queryId, ruleId, category) or
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @id cpp/misra/polymorphic-class-type-expression-in-typeid
* @name RULE-8-2-9: The operand to typeid shall not be an expression of polymorphic class type
* @description It is unclear whether a typeid expression will be evaluated at runtime or compile
* time when its static type is a polymorphic class type.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-8-2-9
* scope/single-translation-unit
* readability
* correctness
* performance
* external/misra/enforcement/decidable
* external/misra/obligation/required
*/

import cpp
import codingstandards.cpp.misra

from TypeidOperator typeid, Expr operand, Class polymorphicClass
where
not isExcluded(typeid, Preconditions1Package::polymorphicClassTypeExpressionInTypeidQuery()) and
operand = typeid.getExpr().getFullyConverted() and
polymorphicClass = operand.getType().getUnderlyingType() and
polymorphicClass.isPolymorphic()
select typeid, "Use of 'typeid' with $@ of polymorphic class type $@.", operand, "expression",
polymorphicClass, polymorphicClass.getName()
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
| test.cpp:41:30:41:39 | typeid ... | Use of 'typeid' with $@ of polymorphic class type $@. | test.cpp:41:37:41:38 | l1 | expression | test.cpp:7:8:7:24 | PolymorphicStruct | PolymorphicStruct |
| test.cpp:42:30:42:40 | typeid ... | Use of 'typeid' with $@ of polymorphic class type $@. | test.cpp:42:37:42:39 | * ... | expression | test.cpp:7:8:7:24 | PolymorphicStruct | PolymorphicStruct |
| test.cpp:43:30:43:39 | typeid ... | Use of 'typeid' with $@ of polymorphic class type $@. | test.cpp:43:37:43:38 | l3 | expression | test.cpp:11:8:11:25 | DerivedPolymorphic | DerivedPolymorphic |
| test.cpp:44:30:44:39 | typeid ... | Use of 'typeid' with $@ of polymorphic class type $@. | test.cpp:44:37:44:38 | l4 | expression | test.cpp:15:7:15:22 | PolymorphicClass | PolymorphicClass |
| test.cpp:57:30:57:39 | typeid ... | Use of 'typeid' with $@ of polymorphic class type $@. | test.cpp:57:37:57:38 | (reference dereference) | expression | test.cpp:7:8:7:24 | PolymorphicStruct | PolymorphicStruct |
| test.cpp:61:30:61:56 | typeid ... | Use of 'typeid' with $@ of polymorphic class type $@. | test.cpp:61:37:61:55 | temporary object | expression | test.cpp:7:8:7:24 | PolymorphicStruct | PolymorphicStruct |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-8-2-9/PolymorphicClassTypeExpressionInTypeid.ql
75 changes: 75 additions & 0 deletions cpp/misra/test/rules/RULE-8-2-9/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <typeinfo>

struct NonPolymorphic {
void foo() {}
};

struct PolymorphicStruct {
virtual void foo() {}
};

struct DerivedPolymorphic : public PolymorphicStruct {
void foo() override {}
};

class PolymorphicClass {
public:
virtual ~PolymorphicClass() = default;
virtual void method() {}
};

void test_typeid_with_type_id() {
const std::type_info &l1 = typeid(NonPolymorphic); // COMPLIANT
const std::type_info &l2 = typeid(PolymorphicStruct); // COMPLIANT
const std::type_info &l3 = typeid(PolymorphicClass); // COMPLIANT
}

void test_typeid_with_non_polymorphic_expression() {
NonPolymorphic l1;
NonPolymorphic *l2 = &l1;

const std::type_info &l3 = typeid(l1); // COMPLIANT
const std::type_info &l4 = typeid(*l2); // COMPLIANT
}

void test_typeid_with_polymorphic_expression() {
PolymorphicStruct l1;
PolymorphicStruct *l2 = &l1;
DerivedPolymorphic l3;
PolymorphicClass l4;

const std::type_info &l5 = typeid(l1); // NON_COMPLIANT
const std::type_info &l6 = typeid(*l2); // NON_COMPLIANT
const std::type_info &l7 = typeid(l3); // NON_COMPLIANT
const std::type_info &l8 = typeid(l4); // NON_COMPLIANT
}

void test_typeid_with_polymorphic_function_call() {
PolymorphicStruct l1;

const std::type_info &l2 = typeid(l1.foo()); // COMPLIANT
}

void test_typeid_with_reference_to_polymorphic() {
PolymorphicStruct l1;
PolymorphicStruct &l2 = l1;

const std::type_info &l3 = typeid(l2); // NON_COMPLIANT
}

void test_typeid_with_polymorphic_temporary() {
const std::type_info &l1 = typeid(PolymorphicStruct{}); // NON_COMPLIANT
}

void test_typeid_with_polymorphic_pointer() {
NonPolymorphic *l1 = new NonPolymorphic();
PolymorphicStruct *l2 = new PolymorphicStruct();
DerivedPolymorphic *l3 = new DerivedPolymorphic();
PolymorphicClass *l4 = new PolymorphicClass();

// Pointer types are not polymorphic themselves
const std::type_info &l5 = typeid(l1); // COMPLIANT
const std::type_info &l6 = typeid(l2); // COMPLIANT
const std::type_info &l7 = typeid(l3); // COMPLIANT
const std::type_info &l8 = typeid(l4); // COMPLIANT
}
27 changes: 27 additions & 0 deletions rule_packages/cpp/Preconditions1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"MISRA-C++-2023": {
"RULE-8-2-9": {
"properties": {
"enforcement": "decidable",
"obligation": "required"
},
"queries": [
{
"description": "It is unclear whether a typeid expression will be evaluated at runtime or compile time when its static type is a polymorphic class type.",
"kind": "problem",
"name": "The operand to typeid shall not be an expression of polymorphic class type",
"precision": "very-high",
"severity": "error",
"short_name": "PolymorphicClassTypeExpressionInTypeid",
"tags": [
"scope/single-translation-unit",
"readability",
"correctness",
"performance"
]
}
],
"title": "The operand to typeid shall not be an expression of polymorphic class type"
}
}
}
2 changes: 1 addition & 1 deletion rules.csv
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ cpp,MISRA-C++-2023,RULE-8-2-5,Yes,Required,Decidable,Single Translation Unit,rei
cpp,MISRA-C++-2023,RULE-8-2-6,Yes,Required,Decidable,Single Translation Unit,"An object with integral, enumerated, or pointer to void type shall not be cast to a pointer type","RULE-11-6, INT36-C",Conversions2,Easy,
cpp,MISRA-C++-2023,RULE-8-2-7,Yes,Advisory,Decidable,Single Translation Unit,A cast should not convert a pointer type to an integral type,"RULE-11-6, INT36-C",Conversions2,Easy,
cpp,MISRA-C++-2023,RULE-8-2-8,Yes,Required,Decidable,Single Translation Unit,An object pointer type shall not be cast to an integral type other than std::uintptr_t or std::intptr_t,"RULE-11-6, INT36-C",Conversions2,Easy,
cpp,MISRA-C++-2023,RULE-8-2-9,Yes,Required,Decidable,Single Translation Unit,The operand to typeid shall not be an expression of polymorphic class type,,Preconditions,Easy,
cpp,MISRA-C++-2023,RULE-8-2-9,Yes,Required,Decidable,Single Translation Unit,The operand to typeid shall not be an expression of polymorphic class type,,Preconditions1,Easy,
cpp,MISRA-C++-2023,RULE-8-2-10,Yes,Required,Undecidable,System,"Functions shall not call themselves, either directly or indirectly",A7-5-2,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-8-2-11,Yes,Required,Decidable,Single Translation Unit,An argument passed via ellipsis shall have an appropriate type,,Preconditions,Easy,
cpp,MISRA-C++-2023,RULE-8-3-1,Yes,Advisory,Decidable,Single Translation Unit,The built-in unary - operator should not be applied to an expression of unsigned type,M5-3-2,ImportMisra23,Import,
Expand Down
Loading