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,44 @@
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
import cpp
import RuleMetadata
import codingstandards.cpp.exclusions.RuleMetadata

newtype Declarations5Query =
TMemberFunctionsRefqualifiedQuery() or
TTypeAliasesDeclarationQuery()

predicate isDeclarations5QueryMetadata(Query query, string queryId, string ruleId, string category) {
query =
// `Query` instance for the `memberFunctionsRefqualified` query
Declarations5Package::memberFunctionsRefqualifiedQuery() and
queryId =
// `@id` for the `memberFunctionsRefqualified` query
"cpp/misra/member-functions-refqualified" and
ruleId = "RULE-6-8-4" and
category = "advisory"
or
query =
// `Query` instance for the `typeAliasesDeclaration` query
Declarations5Package::typeAliasesDeclarationQuery() and
queryId =
// `@id` for the `typeAliasesDeclaration` query
"cpp/misra/type-aliases-declaration" and
ruleId = "RULE-6-9-1" and
category = "required"
}

module Declarations5Package {
Query memberFunctionsRefqualifiedQuery() {
//autogenerate `Query` type
result =
// `Query` type for `memberFunctionsRefqualified` query
TQueryCPP(TDeclarations5PackageQuery(TMemberFunctionsRefqualifiedQuery()))
}

Query typeAliasesDeclarationQuery() {
//autogenerate `Query` type
result =
// `Query` type for `typeAliasesDeclaration` query
TQueryCPP(TDeclarations5PackageQuery(TTypeAliasesDeclarationQuery()))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import DeadCode9
import Declarations
import Declarations1
import Declarations2
import Declarations5
import ExceptionSafety
import Exceptions1
import Exceptions2
Expand Down Expand Up @@ -131,6 +132,7 @@ newtype TCPPQuery =
TDeclarationsPackageQuery(DeclarationsQuery q) or
TDeclarations1PackageQuery(Declarations1Query q) or
TDeclarations2PackageQuery(Declarations2Query q) or
TDeclarations5PackageQuery(Declarations5Query q) or
TExceptionSafetyPackageQuery(ExceptionSafetyQuery q) or
TExceptions1PackageQuery(Exceptions1Query q) or
TExceptions2PackageQuery(Exceptions2Query q) or
Expand Down Expand Up @@ -228,6 +230,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
isDeclarationsQueryMetadata(query, queryId, ruleId, category) or
isDeclarations1QueryMetadata(query, queryId, ruleId, category) or
isDeclarations2QueryMetadata(query, queryId, ruleId, category) or
isDeclarations5QueryMetadata(query, queryId, ruleId, category) or
isExceptionSafetyQueryMetadata(query, queryId, ruleId, category) or
isExceptions1QueryMetadata(query, queryId, ruleId, category) or
isExceptions2QueryMetadata(query, queryId, ruleId, category) or
Expand Down
117 changes: 117 additions & 0 deletions cpp/misra/src/rules/RULE-6-8-4/MemberFunctionsRefqualified.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* @id cpp/misra/member-functions-refqualified
* @name RULE-6-8-4: Member functions returning references to their object should be refqualified appropriately
* @description Member functions that return references to temporary objects (or subobjects) can
* lead to dangling pointers.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-6-8-4
* correctness
* scope/single-translation-unit
* external/misra/enforcement/decidable
* external/misra/obligation/advisory
*/

import cpp
import codingstandards.cpp.misra
import codingstandards.cpp.types.Compatible
import codingstandards.cpp.Operator

class MembersReturningPointerOrRef extends MemberFunction {
MembersReturningPointerOrRef() {
this.getUnspecifiedType() instanceof PointerType or
this.getUnspecifiedType() instanceof ReferenceType
}
}

abstract class MembersReturningObjectOrSubobject extends MembersReturningPointerOrRef {
string toString() { result = "Members returning object or subobject" }
}

class MembersReturningObject extends MembersReturningObjectOrSubobject {
MembersReturningObject() {
exists(ReturnStmt r, ThisExpr t |
r.getEnclosingFunction() = this and
(
r.getAChild*() = t
or
exists(PointerDereferenceExpr p |
p.getAChild*() = t and
r.getAChild*() = p
)
) and
t.getActualType().stripType() = this.getDeclaringType()
)
}
}

class MembersReturningSubObject extends MembersReturningObjectOrSubobject {
MembersReturningSubObject() {
exists(ReturnStmt r, FieldSubObjectDeclaration field |
r.getEnclosingFunction() = this and
(
r.getAChild*() = field.(Field).getAnAccess()
or
exists(PointerDereferenceExpr p |
p.getAChild*() = field.(Field).getAnAccess() and
r.getAChild*() = p
)
) and
field.(Field).getDeclaringType() = this.getDeclaringType()
)
}
}

predicate relevantTypes(Type a, Type b) {
exists(MembersReturningObject f, MemberFunction overload |
f.getAnOverload() = overload and
exists(int i |
f.getParameter(i).getType() = a and
overload.getParameter(i).getType() = b
)
)
}

class AppropriatelyQualified extends MembersReturningObjectOrSubobject {
AppropriatelyQualified() {
//non-const-lvalue-ref-qualified
this.isLValueRefQualified() and
not this.hasSpecifier("const")
or
//const-lvalue-ref-qualified
this.isLValueRefQualified() and
this.hasSpecifier("const") and
//and overload exists that is rvalue-ref-qualified
exists(MemberFunction overload |
this.getAnOverload() = overload and
overload.isRValueRefQualified() and
//and has same param list
forall(int i | exists([this, overload].getParameter(i)) |
TypeEquivalence<TypesCompatibleConfig, relevantTypes/2>::equalTypes(this.getParameter(i)
.getType(), overload.getParameter(i).getType())
)
)
}
}

/**
* Fields that are not reference type can be subobjects
*/
class FieldSubObjectDeclaration extends Declaration {
FieldSubObjectDeclaration() {
not this.getADeclarationEntry().getType() instanceof ReferenceType and
this instanceof Field
}
}

class DefaultedAssignmentOperator extends AssignmentOperator {
DefaultedAssignmentOperator() { this.isDefaulted() }
}

from MembersReturningObjectOrSubobject f
where
not isExcluded(f, Declarations5Package::memberFunctionsRefqualifiedQuery()) and
not f instanceof AppropriatelyQualified and
not f instanceof DefaultedAssignmentOperator
select f, "Member function is not properly ref qualified."
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The query currently produces duplicate results for the same source location (see the repeated test.cpp:42:16 rows in the corresponding .expected). Please adjust the query to avoid duplicates (for example by selecting distinct results and/or normalizing template instantiation/uninstantiated locations similar to other MISRA queries).

Suggested change
select f, "Member function is not properly ref qualified."
select distinct f, "Member function is not properly ref qualified."

Copilot uses AI. Check for mistakes.
33 changes: 33 additions & 0 deletions cpp/misra/src/rules/RULE-6-9-1/TypeAliasesDeclaration.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* @id cpp/misra/type-aliases-declaration
* @name RULE-6-9-1: The same type aliases shall be used in all declarations of the same entity
* @description Using different type aliases on redeclarations can make code hard to understand and
* maintain.
* @kind problem
* @precision very-high
* @problem.severity warning
* @tags external/misra/id/rule-6-9-1
* maintainability
* readability
* scope/single-translation-unit
* external/misra/enforcement/decidable
* external/misra/obligation/required
*/

import cpp
import codingstandards.cpp.misra

from DeclarationEntry decl1, DeclarationEntry decl2, TypedefType t
where
not isExcluded(decl1, Declarations5Package::typeAliasesDeclarationQuery()) and
not isExcluded(decl2, Declarations5Package::typeAliasesDeclarationQuery()) and
not decl1 = decl2 and
decl1.getDeclaration() = decl2.getDeclaration() and
t.getATypeNameUse() = decl1 and
not t.getATypeNameUse() = decl2 and
//exception cases - we dont want to disallow struct typedef name use
not t.getBaseType() instanceof Struct and
not t.getBaseType() instanceof Enum
select decl1,
"Declaration entry has a different type alias than $@ where the type alias used is '$@'.", decl2,
decl2.getName(), t, t.getName()
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
| test.cpp:12:14:12:20 | Members returning object or subobject | Member function is not properly ref qualified. |
| test.cpp:24:12:24:23 | Members returning object or subobject | Member function is not properly ref qualified. |
| test.cpp:28:6:28:18 | Members returning object or subobject | Member function is not properly ref qualified. |
| test.cpp:42:16:42:16 | Members returning object or subobject | Member function is not properly ref qualified. |
| test.cpp:42:16:42:16 | Members returning object or subobject | Member function is not properly ref qualified. |
| test.cpp:42:16:42:16 | Members returning object or subobject | Member function is not properly ref qualified. |
Comment on lines +5 to +6
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .expected output contains three identical rows for the same location (test.cpp:42:16). This indicates the query is emitting duplicates; tests should generally not codify duplicate results. Once the query is de-duplicated, update this expected file accordingly.

Suggested change
| test.cpp:42:16:42:16 | Members returning object or subobject | Member function is not properly ref qualified. |
| test.cpp:42:16:42:16 | Members returning object or subobject | Member function is not properly ref qualified. |

Copilot uses AI. Check for mistakes.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-6-8-4/MemberFunctionsRefqualified.ql
54 changes: 54 additions & 0 deletions cpp/misra/test/rules/RULE-6-8-4/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
struct A {
int a;
int &b;

int &geta() & { return a; } // COMPLIANT

int const &geta2() const & { // COMPLIANT -- due to overload below
return a;
}
int geta2() && { return a; }

int const &getabad() const & { // NON_COMPLIANT -- no overload provided
return a;
}

int getb() && { return b; } // COMPLIANT -- b is not a subobject

A const *getstruct() const & { // COMPLIANT -- due to overload below
return this;
}

A getstruct() const && = delete;

A const *getstructbad() const & { // NON_COMPLIANT -- no overload provided
return this;
}

A &getstructbad2() { return *this; } // NON_COMPLIANT
};

class C {
C *f() { // COMPLIANT -- this is not explicitly designated therefore this is
// not
// relevant for this rule
C *thisclass = this;
return thisclass;
}
};

struct Templ {
template <typename T>
Templ const *f(T) const & { // NON_COMPLIANT -- for an instantiation below
return this;
}

void f(int) const && = delete;
};

void f(int p, float p1) {
Templ t;
t.f(p);
t.f(p1); // instantiation that causes issue due to parameter list type meaning
// there is no overload
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
| test.cpp:4:5:4:5 | definition of i | Declaration entry has a different type alias than $@ where the type alias used is '$@'. | test.cpp:5:12:5:12 | declaration of i | i | test.cpp:1:13:1:15 | INT | INT |
| test.cpp:11:20:11:20 | declaration of i | Declaration entry has a different type alias than $@ where the type alias used is '$@'. | test.cpp:10:12:10:12 | declaration of i | i | test.cpp:2:7:2:11 | Index | Index |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-6-9-1/TypeAliasesDeclaration.ql
15 changes: 15 additions & 0 deletions cpp/misra/test/rules/RULE-6-9-1/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
typedef int INT;
using Index = int;

INT i;
extern int i; // NON_COMPLIANT
Comment on lines +4 to +5
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expected results for this rule report the primary location on INT i; (line 4), but the test marks extern int i; (line 5) as NON_COMPLIANT. Please align the NON_COMPLIANT annotation(s) with the location(s) the query reports (either move/add the annotation to line 4, or adjust the query to report line 5 as the primary location).

Suggested change
INT i;
extern int i; // NON_COMPLIANT
INT i; // NON_COMPLIANT
extern int i;

Copilot uses AI. Check for mistakes.

INT j;
extern INT j; // COMPLIANT

void g(int i);
void g(Index const i); // NON_COMPLIANT

void h(Index i);
void h(Index const i); // COMPLIANT
void h(int *i); // COMPLIANT
47 changes: 47 additions & 0 deletions rule_packages/cpp/Declarations5.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"MISRA-C++-2023": {
"RULE-6-8-4": {
"properties": {
"enforcement": "decidable",
"obligation": "advisory"
},
"queries": [
{
"description": "Member functions that return references to temporary objects (or subobjects) can lead to dangling pointers.",
"kind": "problem",
"name": "Member functions returning references to their object should be refqualified appropriately",
"precision": "very-high",
"severity": "error",
"short_name": "MemberFunctionsRefqualified",
"tags": [
"correctness",
"scope/single-translation-unit"
]
}
],
"title": "Member functions returning references to their object should be refqualified appropriately"
},
"RULE-6-9-1": {
"properties": {
"enforcement": "decidable",
"obligation": "required"
},
"queries": [
{
"description": "Using different type aliases on redeclarations can make code hard to understand and maintain.",
"kind": "problem",
"name": "The same type aliases shall be used in all declarations of the same entity",
"precision": "very-high",
"severity": "warning",
"short_name": "TypeAliasesDeclaration",
"tags": [
"maintainability",
"readability",
"scope/single-translation-unit"
]
}
],
"title": "The same type aliases shall be used in all declarations of the same entity"
}
}
}
4 changes: 2 additions & 2 deletions rules.csv
Original file line number Diff line number Diff line change
Expand Up @@ -867,8 +867,8 @@ cpp,MISRA-C++-2023,RULE-6-7-2,Yes,Required,Decidable,Single Translation Unit,Glo
cpp,MISRA-C++-2023,RULE-6-8-1,Yes,Required,Undecidable,System,An object shall not be accessed outside of its lifetime,A3-8-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-6-8-2,Yes,Mandatory,Decidable,Single Translation Unit,A function must not return a reference or a pointer to a local variable with automatic storage duration,M7-5-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-6-8-3,Yes,Required,Decidable,Single Translation Unit,An assignment operator shall not assign the address of an object with automatic storage duration to an object with a greater lifetime,,Lifetime,Medium,
cpp,MISRA-C++-2023,RULE-6-8-4,Yes,Advisory,Decidable,Single Translation Unit,Member functions returning references to their object should be refqualified appropriately,,Declarations3,Medium,
cpp,MISRA-C++-2023,RULE-6-9-1,Yes,Required,Decidable,Single Translation Unit,The same type aliases shall be used in all declarations of the same entity,,Declarations3,Medium,
cpp,MISRA-C++-2023,RULE-6-8-4,Yes,Advisory,Decidable,Single Translation Unit,Member functions returning references to their object should be refqualified appropriately,,Declarations5,Medium,
cpp,MISRA-C++-2023,RULE-6-9-1,Yes,Required,Decidable,Single Translation Unit,The same type aliases shall be used in all declarations of the same entity,,Declarations5,Medium,
cpp,MISRA-C++-2023,RULE-6-9-2,Yes,Advisory,Decidable,Single Translation Unit,The names of the standard signed integer types and standard unsigned integer types should not be used,A3-9-1,BannedAPIs,Easy,
cpp,MISRA-C++-2023,RULE-7-0-1,Yes,Required,Decidable,Single Translation Unit,There shall be no conversion from type bool,,Conversions,Easy,
cpp,MISRA-C++-2023,RULE-7-0-2,Yes,Required,Decidable,Single Translation Unit,There shall be no conversion to type bool,,Conversions,Easy,
Expand Down
Loading