From f739b65a3fee520caca049539b8a5a6106c53de7 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Thu, 19 Mar 2026 13:40:53 -0400 Subject: [PATCH 1/4] Add RULE-13-3-3 --- .../cpp/exclusions/cpp/Declarations1.qll | 26 ++++++++++ .../cpp/exclusions/cpp/RuleMetadata.qll | 3 ++ ...eclarationsOfAFunctionSameParameterName.ql | 48 +++++++++++++++++++ ...tionsOfAFunctionSameParameterName.expected | 7 +++ ...arationsOfAFunctionSameParameterName.qlref | 1 + .../test/rules/RULE-13-3-3/functions1.cpp | 36 ++++++++++++++ .../test/rules/RULE-13-3-3/functions2.cpp | 17 +++++++ cpp/misra/test/rules/RULE-13-3-3/test.cpp | 0 rule_packages/cpp/Declarations1.json | 26 ++++++++++ rules.csv | 2 +- 10 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations1.qll create mode 100644 cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql create mode 100644 cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.expected create mode 100644 cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.qlref create mode 100644 cpp/misra/test/rules/RULE-13-3-3/functions1.cpp create mode 100644 cpp/misra/test/rules/RULE-13-3-3/functions2.cpp create mode 100644 cpp/misra/test/rules/RULE-13-3-3/test.cpp create mode 100644 rule_packages/cpp/Declarations1.json diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations1.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations1.qll new file mode 100644 index 0000000000..51d68035bc --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations1.qll @@ -0,0 +1,26 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Declarations1Query = TDeclarationsOfAFunctionSameParameterNameQuery() + +predicate isDeclarations1QueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `declarationsOfAFunctionSameParameterName` query + Declarations1Package::declarationsOfAFunctionSameParameterNameQuery() and + queryId = + // `@id` for the `declarationsOfAFunctionSameParameterName` query + "cpp/misra/declarations-of-a-function-same-parameter-name" and + ruleId = "RULE-13-3-3" and + category = "required" +} + +module Declarations1Package { + Query declarationsOfAFunctionSameParameterNameQuery() { + //autogenerate `Query` type + result = + // `Query` type for `declarationsOfAFunctionSameParameterName` query + TQueryCPP(TDeclarations1PackageQuery(TDeclarationsOfAFunctionSameParameterNameQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll index 1aae8da9c7..51e27e49fd 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll @@ -27,6 +27,7 @@ import DeadCode7 import DeadCode8 import DeadCode9 import Declarations +import Declarations1 import ExceptionSafety import Exceptions1 import Exceptions2 @@ -116,6 +117,7 @@ newtype TCPPQuery = TDeadCode8PackageQuery(DeadCode8Query q) or TDeadCode9PackageQuery(DeadCode9Query q) or TDeclarationsPackageQuery(DeclarationsQuery q) or + TDeclarations1PackageQuery(Declarations1Query q) or TExceptionSafetyPackageQuery(ExceptionSafetyQuery q) or TExceptions1PackageQuery(Exceptions1Query q) or TExceptions2PackageQuery(Exceptions2Query q) or @@ -205,6 +207,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat isDeadCode8QueryMetadata(query, queryId, ruleId, category) or isDeadCode9QueryMetadata(query, queryId, ruleId, category) or isDeclarationsQueryMetadata(query, queryId, ruleId, category) or + isDeclarations1QueryMetadata(query, queryId, ruleId, category) or isExceptionSafetyQueryMetadata(query, queryId, ruleId, category) or isExceptions1QueryMetadata(query, queryId, ruleId, category) or isExceptions2QueryMetadata(query, queryId, ruleId, category) or diff --git a/cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql b/cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql new file mode 100644 index 0000000000..862cc88861 --- /dev/null +++ b/cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql @@ -0,0 +1,48 @@ +/** + * @id cpp/misra/declarations-of-a-function-same-parameter-name + * @name RULE-13-3-3: The parameters in all declarations or overrides of a function shall either be unnamed or have identical names + * @description Parameters in some number of declarations or overrides of a function that do not + * have identical names can lead to developer confusion. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-13-3-3 + * maintainability + * readability + * scope/system + * external/misra/enforcement/decidable + * external/misra/obligation/required + */ + +import cpp +import codingstandards.cpp.misra +import codingstandards.cpp.types.Compatible + +predicate parameterNamesUnmatchedOverrides(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) { + pragma[only_bind_into](f1).getFunction().(MemberFunction).getAnOverridingFunction*() = + pragma[only_bind_into](f2).getFunction() and + exists(string p1Name, string p2Name, int i | + p1Name = f1.getParameterDeclarationEntry(i).getName() and + p2Name = f2.getParameterDeclarationEntry(i).getName() + | + not p1Name = p2Name + ) +} + +from FunctionDeclarationEntry f1, FunctionDeclarationEntry f2, string case +where + not isExcluded(f1, Declarations1Package::declarationsOfAFunctionSameParameterNameQuery()) and + not isExcluded(f2, Declarations1Package::declarationsOfAFunctionSameParameterNameQuery()) and + not f1 = f2 and + ( + f1.getDeclaration() = f2.getDeclaration() and + parameterNamesUnmatched(f1, f2) and + case = "re-declaration" + or + f1.getFunction().(MemberFunction).getAnOverridingFunction*() = f2.getFunction() and + parameterNamesUnmatchedOverrides(f1, f2) and + case = "override" + ) +select f1, + "The parameter names of " + case + " of $@ do" + " not use the same names as declaration $@", f1, + f1.getName(), f2, f2.getName() diff --git a/cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.expected b/cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.expected new file mode 100644 index 0000000000..dec2b26ffc --- /dev/null +++ b/cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.expected @@ -0,0 +1,7 @@ +| functions1.cpp:5:6:5:7 | declaration of f4 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions1.cpp:5:6:5:7 | declaration of f4 | f4 | functions2.cpp:6:6:6:7 | declaration of f4 | f4 | +| functions1.cpp:6:6:6:7 | declaration of f5 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions1.cpp:6:6:6:7 | declaration of f5 | f5 | functions2.cpp:7:6:7:7 | declaration of f5 | f5 | +| functions1.cpp:16:6:16:7 | definition of f7 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions1.cpp:16:6:16:7 | definition of f7 | f7 | functions2.cpp:15:13:15:14 | declaration of f7 | f7 | +| functions1.cpp:29:16:29:22 | declaration of methodA | The parameter names of override of $@ do not use the same names as declaration $@ | functions1.cpp:29:16:29:22 | declaration of methodA | methodA | functions1.cpp:34:8:34:14 | declaration of methodA | methodA | +| functions2.cpp:6:6:6:7 | declaration of f4 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions2.cpp:6:6:6:7 | declaration of f4 | f4 | functions1.cpp:5:6:5:7 | declaration of f4 | f4 | +| functions2.cpp:7:6:7:7 | declaration of f5 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions2.cpp:7:6:7:7 | declaration of f5 | f5 | functions1.cpp:6:6:6:7 | declaration of f5 | f5 | +| functions2.cpp:15:13:15:14 | declaration of f7 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions2.cpp:15:13:15:14 | declaration of f7 | f7 | functions1.cpp:16:6:16:7 | definition of f7 | f7 | diff --git a/cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.qlref b/cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.qlref new file mode 100644 index 0000000000..7cb81c0bad --- /dev/null +++ b/cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.qlref @@ -0,0 +1 @@ +rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql \ No newline at end of file diff --git a/cpp/misra/test/rules/RULE-13-3-3/functions1.cpp b/cpp/misra/test/rules/RULE-13-3-3/functions1.cpp new file mode 100644 index 0000000000..c53f61392f --- /dev/null +++ b/cpp/misra/test/rules/RULE-13-3-3/functions1.cpp @@ -0,0 +1,36 @@ +void f1(int a); // COMPLIANT -- same name +void f2(int a); // COMPLIANT -- unnamed is fine + +void f3(int a); // COMPLIANT -- diff number but for those that exist, same +void f4(int p, int b); // NON_COMPLIANT -- diff name +void f5(int b, int a); // NON_COMPLIANT -- swapped names + +typedef int wi; +typedef int hi; +typedef long a; + +a f6(wi w, wi h) { // NON_COMPLIANT + return (a)w * h; +} + +void f7(int b, int a) { // NON_COMPLIANT + return; +} + +void f8(int a) { // COMPLIANT + return; +} + +template void f9(T t); // COMPLIANT +template <> +void f9(int i); // COMPLIANT - specialization is a diff declaration + +class ClassA { + virtual void methodA(int i); // NON_COMPLIANT + virtual void methodB(int i); // COMPLIANT +}; + +class ClassB : ClassA { + void methodA(int d) override; + void methodB(int i) override; +}; \ No newline at end of file diff --git a/cpp/misra/test/rules/RULE-13-3-3/functions2.cpp b/cpp/misra/test/rules/RULE-13-3-3/functions2.cpp new file mode 100644 index 0000000000..fa4ee611c9 --- /dev/null +++ b/cpp/misra/test/rules/RULE-13-3-3/functions2.cpp @@ -0,0 +1,17 @@ +void f1(int a); // COMPLIANT -- same name +void f2(int); // COMPLIANT -- unnamed is fine + +void f3(int a, + int b); // COMPLIANT -- diff number but for those that exist, same +void f4(int a, int b); // NON_COMPLIANT -- diff name +void f5(int a, int b); // NON_COMPLIANT -- swapped names + +typedef int wi; +typedef int hi; +typedef long a; + +extern a f6(wi w, hi h); // NON_COMPLIANT + +extern void f7(int a, int b); // NON_COMPLIANT + +extern void f8(int); // COMPLIANT \ No newline at end of file diff --git a/cpp/misra/test/rules/RULE-13-3-3/test.cpp b/cpp/misra/test/rules/RULE-13-3-3/test.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/rule_packages/cpp/Declarations1.json b/rule_packages/cpp/Declarations1.json new file mode 100644 index 0000000000..2e321fdb32 --- /dev/null +++ b/rule_packages/cpp/Declarations1.json @@ -0,0 +1,26 @@ +{ + "MISRA-C++-2023": { + "RULE-13-3-3": { + "properties": { + "enforcement": "decidable", + "obligation": "required" + }, + "queries": [ + { + "description": "Parameters in some number of declarations or overrides of a function that do not have identical names can lead to developer confusion.", + "kind": "problem", + "name": "The parameters in all declarations or overrides of a function shall either be unnamed or have identical names", + "precision": "very-high", + "severity": "error", + "short_name": "DeclarationsOfAFunctionSameParameterName", + "tags": [ + "maintainability", + "readability", + "scope/system" + ] + } + ], + "title": "The parameters in all declarations or overrides of a function shall either be unnamed or have identical names" + } + } +} \ No newline at end of file diff --git a/rules.csv b/rules.csv index 90e5c6e3d8..69e319c368 100644 --- a/rules.csv +++ b/rules.csv @@ -935,7 +935,7 @@ cpp,MISRA-C++-2023,RULE-13-1-1,Yes,Advisory,Decidable,Single Translation Unit,Cl cpp,MISRA-C++-2023,RULE-13-1-2,Yes,Required,Decidable,Single Translation Unit,An accessible base class shall not be both virtual and non-virtual in the same hierarchy,M10-1-3,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-13-3-1,Yes,Required,Decidable,Single Translation Unit,"User-declared member functions shall use the virtual, override and final specifiers appropriately",,Classes2,Easy, cpp,MISRA-C++-2023,RULE-13-3-2,Yes,Required,Decidable,Single Translation Unit,Parameters in an overriding virtual function shall not specify different default arguments,M8-3-1,ImportMisra23,Import, -cpp,MISRA-C++-2023,RULE-13-3-3,Yes,Required,Decidable,System,The parameters in all declarations or overrides of a function shall either be unnamed or have identical names,RULE-8-3,Declarations2,Easy, +cpp,MISRA-C++-2023,RULE-13-3-3,Yes,Required,Decidable,System,The parameters in all declarations or overrides of a function shall either be unnamed or have identical names,RULE-8-3,Declarations1,Easy, cpp,MISRA-C++-2023,RULE-13-3-4,Yes,Required,Decidable,Single Translation Unit,A comparison of a potentially virtual pointer to member function shall only be with nullptr,A5-10-1,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-14-1-1,Yes,Advisory,Decidable,Single Translation Unit,Non-static data members should be either all private or all public,,Classes2,Easy, cpp,MISRA-C++-2023,RULE-15-0-1,Yes,Required,Decidable,Single Translation Unit,Special member functions shall be provided appropriately,A12-0-1,Classes3,Medium, From f999e104d7b462e3e2489e59750c96272330aa7b Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Thu, 19 Mar 2026 16:35:20 -0400 Subject: [PATCH 2/4] Fix testcase labelling RULE-13-3-3 --- ...arationsOfAFunctionSameParameterName.expected | 6 +++--- cpp/misra/test/rules/RULE-13-3-3/functions1.cpp | 16 ++++------------ cpp/misra/test/rules/RULE-13-3-3/functions2.cpp | 10 ++-------- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.expected b/cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.expected index dec2b26ffc..6472ae2e99 100644 --- a/cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.expected +++ b/cpp/misra/test/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.expected @@ -1,7 +1,7 @@ | functions1.cpp:5:6:5:7 | declaration of f4 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions1.cpp:5:6:5:7 | declaration of f4 | f4 | functions2.cpp:6:6:6:7 | declaration of f4 | f4 | | functions1.cpp:6:6:6:7 | declaration of f5 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions1.cpp:6:6:6:7 | declaration of f5 | f5 | functions2.cpp:7:6:7:7 | declaration of f5 | f5 | -| functions1.cpp:16:6:16:7 | definition of f7 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions1.cpp:16:6:16:7 | definition of f7 | f7 | functions2.cpp:15:13:15:14 | declaration of f7 | f7 | -| functions1.cpp:29:16:29:22 | declaration of methodA | The parameter names of override of $@ do not use the same names as declaration $@ | functions1.cpp:29:16:29:22 | declaration of methodA | methodA | functions1.cpp:34:8:34:14 | declaration of methodA | methodA | +| functions1.cpp:8:6:8:7 | definition of f6 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions1.cpp:8:6:8:7 | definition of f6 | f6 | functions2.cpp:9:13:9:14 | declaration of f6 | f6 | +| functions1.cpp:21:16:21:22 | declaration of methodA | The parameter names of override of $@ do not use the same names as declaration $@ | functions1.cpp:21:16:21:22 | declaration of methodA | methodA | functions1.cpp:26:8:26:14 | declaration of methodA | methodA | | functions2.cpp:6:6:6:7 | declaration of f4 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions2.cpp:6:6:6:7 | declaration of f4 | f4 | functions1.cpp:5:6:5:7 | declaration of f4 | f4 | | functions2.cpp:7:6:7:7 | declaration of f5 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions2.cpp:7:6:7:7 | declaration of f5 | f5 | functions1.cpp:6:6:6:7 | declaration of f5 | f5 | -| functions2.cpp:15:13:15:14 | declaration of f7 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions2.cpp:15:13:15:14 | declaration of f7 | f7 | functions1.cpp:16:6:16:7 | definition of f7 | f7 | +| functions2.cpp:9:13:9:14 | declaration of f6 | The parameter names of re-declaration of $@ do not use the same names as declaration $@ | functions2.cpp:9:13:9:14 | declaration of f6 | f6 | functions1.cpp:8:6:8:7 | definition of f6 | f6 | diff --git a/cpp/misra/test/rules/RULE-13-3-3/functions1.cpp b/cpp/misra/test/rules/RULE-13-3-3/functions1.cpp index c53f61392f..758572b2d3 100644 --- a/cpp/misra/test/rules/RULE-13-3-3/functions1.cpp +++ b/cpp/misra/test/rules/RULE-13-3-3/functions1.cpp @@ -5,25 +5,17 @@ void f3(int a); // COMPLIANT -- diff number but for those that exist, same void f4(int p, int b); // NON_COMPLIANT -- diff name void f5(int b, int a); // NON_COMPLIANT -- swapped names -typedef int wi; -typedef int hi; -typedef long a; - -a f6(wi w, wi h) { // NON_COMPLIANT - return (a)w * h; -} - -void f7(int b, int a) { // NON_COMPLIANT +void f6(int b, int a) { // NON_COMPLIANT return; } -void f8(int a) { // COMPLIANT +void f7(int a) { // COMPLIANT return; } -template void f9(T t); // COMPLIANT +template void f8(T t); // COMPLIANT template <> -void f9(int i); // COMPLIANT - specialization is a diff declaration +void f8(int i); // COMPLIANT - specialization is a diff declaration class ClassA { virtual void methodA(int i); // NON_COMPLIANT diff --git a/cpp/misra/test/rules/RULE-13-3-3/functions2.cpp b/cpp/misra/test/rules/RULE-13-3-3/functions2.cpp index fa4ee611c9..4f8a148231 100644 --- a/cpp/misra/test/rules/RULE-13-3-3/functions2.cpp +++ b/cpp/misra/test/rules/RULE-13-3-3/functions2.cpp @@ -6,12 +6,6 @@ void f3(int a, void f4(int a, int b); // NON_COMPLIANT -- diff name void f5(int a, int b); // NON_COMPLIANT -- swapped names -typedef int wi; -typedef int hi; -typedef long a; +extern void f6(int a, int b); // NON_COMPLIANT -extern a f6(wi w, hi h); // NON_COMPLIANT - -extern void f7(int a, int b); // NON_COMPLIANT - -extern void f8(int); // COMPLIANT \ No newline at end of file +extern void f7(int); // COMPLIANT \ No newline at end of file From c6997fd883160b8aee841d1d494794f450bef42e Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Thu, 19 Mar 2026 16:41:58 -0400 Subject: [PATCH 3/4] Address review comment --- .../RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql b/cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql index 862cc88861..f55bf7f8ad 100644 --- a/cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql +++ b/cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql @@ -39,7 +39,6 @@ where parameterNamesUnmatched(f1, f2) and case = "re-declaration" or - f1.getFunction().(MemberFunction).getAnOverridingFunction*() = f2.getFunction() and parameterNamesUnmatchedOverrides(f1, f2) and case = "override" ) From a4ca1489fc64d82032e9ec4f42bbe57df2e917a6 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Thu, 19 Mar 2026 16:45:02 -0400 Subject: [PATCH 4/4] Apply a few other review comments --- .../DeclarationsOfAFunctionSameParameterName.ql | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql b/cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql index f55bf7f8ad..9f96d36fcb 100644 --- a/cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql +++ b/cpp/misra/src/rules/RULE-13-3-3/DeclarationsOfAFunctionSameParameterName.ql @@ -19,7 +19,7 @@ import codingstandards.cpp.misra import codingstandards.cpp.types.Compatible predicate parameterNamesUnmatchedOverrides(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) { - pragma[only_bind_into](f1).getFunction().(MemberFunction).getAnOverridingFunction*() = + pragma[only_bind_into](f1).getFunction().(MemberFunction).getAnOverridingFunction+() = pragma[only_bind_into](f2).getFunction() and exists(string p1Name, string p2Name, int i | p1Name = f1.getParameterDeclarationEntry(i).getName() and @@ -42,6 +42,5 @@ where parameterNamesUnmatchedOverrides(f1, f2) and case = "override" ) -select f1, - "The parameter names of " + case + " of $@ do" + " not use the same names as declaration $@", f1, - f1.getName(), f2, f2.getName() +select f1, "The parameter names of " + case + " of $@ do not use the same names as declaration $@", + f1, f1.getName(), f2, f2.getName()