From ef6492b3553e3c919b843e172163f517ba9f726a Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Wed, 1 Apr 2026 23:40:48 -0700 Subject: [PATCH 01/10] initial commit --- .../cpp/exclusions/cpp/Declarations3.qll | 26 ++ .../cpp/exclusions/cpp/RuleMetadata.qll | 3 + .../test/includes/standard-library/vector.h | 4 +- .../RULE-10-1-1/PointerOrRefParamNotConst.ql | 201 ++++++++++++++ .../PointerOrRefParamNotConst.expected | 70 +++++ .../PointerOrRefParamNotConst.qlref | 1 + cpp/misra/test/rules/RULE-10-1-1/test.cpp | 247 ++++++++++++++++++ rule_packages/cpp/Declarations3.json | 26 ++ rules.csv | 2 +- 9 files changed, 577 insertions(+), 3 deletions(-) create mode 100644 cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations3.qll create mode 100644 cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql create mode 100644 cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected create mode 100644 cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.qlref create mode 100644 cpp/misra/test/rules/RULE-10-1-1/test.cpp create mode 100644 rule_packages/cpp/Declarations3.json diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations3.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations3.qll new file mode 100644 index 0000000000..47d0d1bf85 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations3.qll @@ -0,0 +1,26 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Declarations3Query = TPointerOrRefParamNotConstQuery() + +predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `pointerOrRefParamNotConst` query + Declarations3Package::pointerOrRefParamNotConstQuery() and + queryId = + // `@id` for the `pointerOrRefParamNotConst` query + "cpp/misra/pointer-or-ref-param-not-const" and + ruleId = "RULE-10-1-1" and + category = "advisory" +} + +module Declarations3Package { + Query pointerOrRefParamNotConstQuery() { + //autogenerate `Query` type + result = + // `Query` type for `pointerOrRefParamNotConst` query + TQueryCPP(TDeclarations3PackageQuery(TPointerOrRefParamNotConstQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll index 1ef6ce7758..999882d81b 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll @@ -28,6 +28,7 @@ import DeadCode8 import DeadCode9 import Declarations import Declarations1 +import Declarations3 import ExceptionSafety import Exceptions1 import Exceptions2 @@ -119,6 +120,7 @@ newtype TCPPQuery = TDeadCode9PackageQuery(DeadCode9Query q) or TDeclarationsPackageQuery(DeclarationsQuery q) or TDeclarations1PackageQuery(Declarations1Query q) or + TDeclarations3PackageQuery(Declarations3Query q) or TExceptionSafetyPackageQuery(ExceptionSafetyQuery q) or TExceptions1PackageQuery(Exceptions1Query q) or TExceptions2PackageQuery(Exceptions2Query q) or @@ -210,6 +212,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat isDeadCode9QueryMetadata(query, queryId, ruleId, category) or isDeclarationsQueryMetadata(query, queryId, ruleId, category) or isDeclarations1QueryMetadata(query, queryId, ruleId, category) or + isDeclarations3QueryMetadata(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/common/test/includes/standard-library/vector.h b/cpp/common/test/includes/standard-library/vector.h index 543d80eca5..e4d0a75a5c 100644 --- a/cpp/common/test/includes/standard-library/vector.h +++ b/cpp/common/test/includes/standard-library/vector.h @@ -20,8 +20,8 @@ template > class vector { iterator begin(); iterator end(); - const_iterator cbegin(); - const_iterator cend(); + const_iterator cbegin() const; + const_iterator cend() const; size_type size() const noexcept; void resize(size_type sz); void resize(size_type sz, const T &c); diff --git a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql new file mode 100644 index 0000000000..d725f38255 --- /dev/null +++ b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql @@ -0,0 +1,201 @@ +/** + * @id cpp/misra/pointer-or-ref-param-not-const + * @name RULE-10-1-1: The target type of a pointer or lvalue reference parameter should be const-qualified appropriately + * @description Pointer or lvalue reference parameters that do not modify the target object should + * be const-qualified to accurately reflect function behavior and prevent unintended + * modifications. + * @kind problem + * @precision high + * @problem.severity warning + * @tags external/misra/id/rule-10-1-1 + * maintainability + * readability + * scope/single-translation-unit + * external/misra/enforcement/decidable + * external/misra/obligation/advisory + */ + +import cpp +import codingstandards.cpp.misra +import codingstandards.cpp.types.Pointers +import codingstandards.cpp.SideEffect +import codingstandards.cpp.alertreporting.HoldsForAllCopies + +/** + * Holds if the function is in a template scope and should be excluded. + */ +predicate isInTemplateScope(Function f) { + // Function templates + f.isFromTemplateInstantiation(_) + or + f instanceof TemplateFunction + or + // Functions declared within the scope of a template class + exists(TemplateClass tc | f.getDeclaringType() = tc) + or + f.getDeclaringType().isFromTemplateInstantiation(_) + or + // Lambdas within template scope + exists(LambdaExpression le | + le.getLambdaFunction() = f and + isInTemplateScope(le.getEnclosingFunction()) + ) +} + +/** + * A `Type` that may be a pointer, array, or reference, to a const or a non-const type. + * + * For example, `const int*`, `int* const`, `cont int* const`, `int*`, `int&`, `const int&` are all + * `PointerLikeType`s, while `int`, `int&&`, and `const int` are not. + * + * To check if a `PointerLikeType` points/refers to a const-qualified type, use the `pointsToConst()` + * predicate. + */ +class PointerLikeType extends Type { + Type innerType; + Type outerType; + + PointerLikeType() { + innerType = this.(UnspecifiedPointerOrArrayType).getBaseType() and + outerType = this + or + innerType = this.(LValueReferenceType).getBaseType() and + outerType = this + or + exists(PointerLikeType stripped | + stripped = this.stripTopLevelSpecifiers() and not stripped = this + | + innerType = stripped.getInnerType() and + outerType = stripped.getOuterType() + ) + } + + /** + * Get the pointed to or referred to type, for instance `int` for `int*` or `const int&`. + */ + Type getInnerType() { result = innerType } + + /** + * Get the resolved pointer, array, or reference type itself, for instance `int*` in `int* const`. + * + * Removes cv-qualification and resolves typedefs and decltypes and specifiers via + * `stripTopLevelSpecifiers()`. + */ + Type getOuterType() { result = outerType } + + /** + * Holds when this type points to const -- for example, `const int*` and `const int&` point to + * const, while `int*`, `int *const` and `int&` do not. + */ + predicate pointsToConst() { innerType.isConst() } + + /** + * Holds when this type points to non-const -- for example, `int*` and `int&` and `int const*` + * point to non-const, while `const int*`, `const int&` do not. + */ + predicate pointsToNonConst() { not innerType.isConst() } +} + +class PointerLikeParam extends Parameter { + PointerLikeType pointerLikeType; + + PointerLikeParam() { + pointerLikeType = this.getType() and + not pointerLikeType.pointsToConst() and + // Exclude pointers to non-object types + not pointerLikeType.getInnerType() instanceof RoutineType and + not pointerLikeType.getInnerType() instanceof VoidType + } + + Expr getAPointerLikeAccess() { + result = this.getAnAccess() + or + // For reference parameters, also consider accesses to the parameter itself as accesses to the referent + pointerLikeType.getOuterType() instanceof ReferenceType and + result.(AddressOfExpr).getOperand() = this.getAnAccess() + or + // A pointer is dereferenced, but the result is not copied + pointerLikeType.getOuterType() instanceof PointerType and + result.(PointerDereferenceExpr).getOperand() = this.getAnAccess() and + not any(ReferenceDereferenceExpr rde).getExpr() = result.getConversion+() + } +} + +query predicate test( + PointerLikeParam param, Expr ptrLikeAccess, Type argtype, Type innerType, string explain +) { + ptrLikeAccess = param.getAPointerLikeAccess() and + exists(FunctionCall fc | + fc.getArgument(0) = ptrLikeAccess and + argtype = fc.getTarget().getParameter(0).getType() and + argtype.(PointerLikeType).pointsToNonConst() and + innerType = argtype.(PointerLikeType).getInnerType() + ) and + explain = argtype.explain() +} + +/** + * A candidate parameter that could have its target type const-qualified. + */ +class NonConstParam extends PointerLikeParam { + NonConstParam() { + not pointerLikeType.pointsToConst() and + // Ignore parameters in functions without bodies + exists(this.getFunction().getBlock()) and + // Ignore unnamed parameters + this.isNamed() and + // Ignore functions that use ASM statements + not exists(AsmStmt a | a.getEnclosingFunction() = this.getFunction()) and + // Must have a pointer, array, or lvalue reference type with non-const target + // Exclude pointers to non-object types + not pointerLikeType.getInnerType() instanceof RoutineType and + not pointerLikeType.getInnerType() instanceof VoidType and + // Exclude virtual functions + not this.getFunction().isVirtual() and + // Exclude functions in template scope + not isInTemplateScope(this.getFunction()) and + // Exclude main + not this.getFunction().hasGlobalName("main") and + // Exclude deleted functions + not this.getFunction().isDeleted() and + // Exclude any parameter whose underlying data is modified (VariableEffect) + not exists(VariableEffect effect | + effect.getTarget() = this and + ( + // For reference types, any effect is a target modification + pointerLikeType.getOuterType() instanceof ReferenceType + or + // For pointer types, exclude effects that only modify the pointer itself + not effect.(AssignExpr).getLValue() = this.getAnAccess() and + not effect.(CrementOperation).getOperand() = this.getAnAccess() + ) + ) and + // Exclude parameters passed as arguments to functions taking non-const pointer/ref params + not exists(FunctionCall fc, int i | + fc.getArgument(i) = this.getAPointerLikeAccess() and + fc.getTarget().getParameter(i).getType().(PointerLikeType).pointsToNonConst() + ) and + // Exclude parameters used as qualifier for a non-const member function + not exists(FunctionCall fc | + fc.getQualifier() = this.getAnAccess() and + not fc.getTarget().hasSpecifier("const") and + not fc.getTarget().isStatic() + ) and + // Exclude parameters assigned to a non-const pointer/reference alias + not exists(Variable v | + v.getAnAssignedValue() = this.getAnAccess() and + v.getType().(PointerLikeType).pointsToNonConst() + ) and + // Exclude parameters returned as non-const pointer/reference + not exists(ReturnStmt ret | + ret.getExpr() = this.getAnAccess() and + ret.getEnclosingFunction().getType().(PointerLikeType).pointsToNonConst() + ) + } +} + +from NonConstParam param +where not isExcluded(param, Declarations3Package::pointerOrRefParamNotConstQuery()) +select param, + "Parameter '" + param.getName() + + "' points/refers to a non-const-qualified type but does not modify the target object." diff --git a/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected b/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected new file mode 100644 index 0000000000..f59c23c14c --- /dev/null +++ b/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected @@ -0,0 +1,70 @@ +test +| test.cpp:44:20:44:21 | p1 | test.cpp:44:35:44:37 | * ... | file://:0:0:0:0 | int32_t & | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | reference to {typedef {signed int} as "int32_t"} | +| test.cpp:53:20:53:21 | p1 | test.cpp:53:35:53:36 | p1 | file://:0:0:0:0 | int32_t & | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | reference to {typedef {signed int} as "int32_t"} | +| test.cpp:59:20:59:21 | p1 | test.cpp:59:35:59:36 | p1 | file://:0:0:0:0 | int32_t * | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | pointer to {typedef {signed int} as "int32_t"} | +| test.cpp:65:20:65:21 | p1 | test.cpp:65:36:65:37 | p1 | file://:0:0:0:0 | int32_t *const | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | const {pointer to {typedef {signed int} as "int32_t"}} | +| test.cpp:69:20:69:21 | p1 | test.cpp:69:35:69:37 | & ... | file://:0:0:0:0 | int32_t * | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | pointer to {typedef {signed int} as "int32_t"} | +| test.cpp:75:20:75:21 | p1 | test.cpp:75:36:75:38 | & ... | file://:0:0:0:0 | int32_t *const | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | const {pointer to {typedef {signed int} as "int32_t"}} | +#select +| test.cpp:4:22:4:23 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:7:28:7:29 | p4 | Parameter 'p4' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:8:21:8:22 | p5 | Parameter 'p5' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:19:36:19:37 | l2 | Parameter 'l2' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:40:20:40:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:41:20:41:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:42:20:42:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:43:20:43:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:45:20:45:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:46:20:46:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:50:20:50:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:51:20:51:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:54:20:54:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:55:20:55:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:60:20:60:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:61:20:61:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:62:20:62:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:63:20:63:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:68:20:68:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:70:20:70:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:71:20:71:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:72:20:72:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:73:20:73:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:74:20:74:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:78:20:78:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:79:20:79:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:80:20:80:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:82:20:82:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:84:20:84:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:89:20:89:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:91:20:91:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:92:20:92:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:93:20:93:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:94:20:94:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:95:20:95:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:100:20:100:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:102:20:102:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:103:20:103:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:104:20:104:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:105:20:105:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:106:20:106:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:142:26:142:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:143:26:143:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:144:26:144:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:145:26:145:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:146:26:146:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:147:26:147:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:148:12:148:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:149:12:149:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:150:12:150:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:151:12:151:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:152:12:152:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:153:12:153:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:156:23:156:24 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:164:23:164:24 | p9 | Parameter 'p9' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:165:23:165:25 | p10 | Parameter 'p10' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:167:23:167:25 | p12 | Parameter 'p12' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:198:12:198:13 | p2 | Parameter 'p2' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:199:12:199:13 | p3 | Parameter 'p3' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:206:23:206:24 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:208:23:208:24 | p3 | Parameter 'p3' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:209:23:209:24 | p4 | Parameter 'p4' points/refers to a non-const-qualified type but does not modify the target object. | diff --git a/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.qlref b/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.qlref new file mode 100644 index 0000000000..f72df6a5ba --- /dev/null +++ b/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.qlref @@ -0,0 +1 @@ +rules/RULE-10-1-1/PointerOrRefParamNotConst.ql \ No newline at end of file diff --git a/cpp/misra/test/rules/RULE-10-1-1/test.cpp b/cpp/misra/test/rules/RULE-10-1-1/test.cpp new file mode 100644 index 0000000000..73b49bacba --- /dev/null +++ b/cpp/misra/test/rules/RULE-10-1-1/test.cpp @@ -0,0 +1,247 @@ +#include +#include + +void f1(std::int8_t *p1, // NON_COMPLIANT - *p1 not modified + const std::int8_t *p2, // COMPLIANT - already const + std::int8_t *p3, // COMPLIANT - *p3 modified + std::int8_t *const p4, // NON_COMPLIANT - *p4 not modified + std::int8_t p5[3]) { // NON_COMPLIANT - array decays to pointer + *p3 = *p1 + *p2 + *p4 + p5[2]; +} + +void f2(std::int32_t &l1, // COMPLIANT - modified + std::int32_t &&l2, // COMPLIANT - rvalue reference, rule N/A + std::int32_t &) { // COMPLIANT - unnamed, rule N/A + l1 = 0; +} + +auto f3(std::vector &l1, // COMPLIANT - x.begin() is non-const + std::vector &l2 // NON_COMPLIANT - cbegin is const +) { + l1.begin(); + l2.cbegin(); +} + +int32_t i32; +int32_t *ptr; +const int32_t *cptr; +int32_t &ref = i32; +void take_i32(std::int32_t l1); +void take_ptr(std::int32_t *l1); +void take_cptr(const std::int32_t *l1); +void take_cptrc(const std::int32_t *const l1); +void take_ptrc(std::int32_t *const l1); +void take_ref(std::int32_t &l1); +void take_cref(const std::int32_t &l1); + +void f4() { + // Pointers used as values + [](std::int32_t *p1) { *p1 = 0; }; // COMPLIANT + [](std::int32_t *p1) { p1 = nullptr; }; // NON_COMPLIANT UNHANDLED + [](std::int32_t *p1) { i32 = *p1; }; // NON_COMPLIANT + [](std::int32_t *p1) { take_i32(*p1); }; // NON_COMPLIANT + [](std::int32_t *p1) { ref = *p1; }; // COMPLIANT UNHANDLED + [](std::int32_t *p1) { take_ref(*p1); }; // COMPLIANT + [](std::int32_t *p1) { const int &l1 = *p1; }; // NON_COMPLIANT + [](std::int32_t *p1) { take_cref(*p1); }; // NON_COMPLIANT + + // References used as values + [](std::int32_t &p1) { p1 = 0; }; // NON_COMPLIANT UNHANDLED + [](std::int32_t &p1) { i32 = p1; }; // NON_COMPLIANT + [](std::int32_t &p1) { take_i32(p1); }; // NON_COMPLIANT + [](std::int32_t &p1) { ref = p1; }; // COMPLIANT + [](std::int32_t &p1) { take_ref(p1); }; // COMPLIANT + [](std::int32_t &p1) { const int &l1 = p1; }; // NON_COMPLIANT + [](std::int32_t &p1) { take_cref(p1); }; // NON_COMPLIANT + + // Pointers used as pointers + [](std::int32_t *p1) { ptr = p1; }; // COMPLIANT + [](std::int32_t *p1) { take_ptr(p1); }; // COMPLIANT + [](std::int32_t *p1) { cptr = p1; }; // NON_COMPLIANT + [](std::int32_t *p1) { take_cptr(p1); }; // NON_COMPLIANT + [](std::int32_t *p1) { const std::int32_t *const l1 = p1; }; // NON_COMPLIANT + [](std::int32_t *p1) { take_cptrc(p1); }; // NON_COMPLIANT + [](std::int32_t *p1) { std::int32_t *const l1 = p1; }; // COMPLIANT + [](std::int32_t *p1) { take_ptrc(p1); }; // COMPLIANT + + // Taking addresses of references parameter + [](std::int32_t &p1) { ptr = &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) { take_ptr(&p1); }; // COMPLIANT + [](std::int32_t &p1) { cptr = &p1; }; // NON_COMPLIANT + [](std::int32_t &p1) { take_cptr(&p1); }; // NON_COMPLIANT + [](std::int32_t &p1) { const std::int32_t *const l1 = &p1; }; // NON_COMPLIANT + [](std::int32_t &p1) { take_cptrc(&p1); }; // NON_COMPLIANT + [](std::int32_t &p1) { std::int32_t *const l1 = &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) { take_ptrc(&p1); }; // COMPLIANT + + // Returning from pointer parameters + [](std::int32_t *p1) -> std::int32_t { return *p1; }; // NON_COMPLIANT + [](std::int32_t *p1) -> std::int32_t & { return *p1; }; // COMPLIANT UNHANDLED + [](std::int32_t *p1) -> const std::int32_t & { return *p1; }; // NON_COMPLIANT + [](std::int32_t *p1) -> std::int32_t * { return p1; }; // COMPLIANT + [](std::int32_t *p1) -> const std::int32_t * { return p1; }; // NON_COMPLIANT + [](std::int32_t *p1) -> std::int32_t *const { return p1; }; // COMPLIANT + [](std::int32_t *p1) -> const std::int32_t *const { + return p1; + }; // NON_COMPLIANT + + // Returning from reference parameters + [](std::int32_t &p1) -> std::int32_t { return p1; }; // NON_COMPLIANT + [](std::int32_t &p1) -> std::int32_t & { return p1; }; // COMPLIANT + [](std::int32_t &p1) -> const std::int32_t & { return p1; }; // NON_COMPLIANT + [](std::int32_t &p1) -> std::int32_t * { return &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) -> const std::int32_t * { return &p1; }; // NON_COMPLIANT + [](std::int32_t &p1) -> std::int32_t *const { return &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) -> const std::int32_t *const { + return &p1; + }; // NON_COMPLIANT + + // Returning from reference parameters + [](std::int32_t &p1) -> std::int32_t { return p1; }; // NON_COMPLIANT + [](std::int32_t &p1) -> std::int32_t & { return p1; }; // COMPLIANT + [](std::int32_t &p1) -> const std::int32_t & { return p1; }; // NON_COMPLIANT + [](std::int32_t &p1) -> std::int32_t * { return &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) -> const std::int32_t * { return &p1; }; // NON_COMPLIANT + [](std::int32_t &p1) -> std::int32_t *const { return &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) -> const std::int32_t *const { + return &p1; + }; // NON_COMPLIANT + + // Non compliant cases are compliant when const + using cpi32 = const std::int32_t *; + using cri32 = const std::int32_t &; + [](const std::int32_t *p1) { p1 = nullptr; }; // COMPLIANT + [](const std::int32_t *p1) { i32 = *p1; }; // COMPLIANT + [](const std::int32_t *p1) { take_i32(*p1); }; // COMPLIANT + [](const std::int32_t *p1) { const int &l1 = *p1; }; // COMPLIANT + [](const std::int32_t *p1) { take_cref(*p1); }; // COMPLIANT + [](const std::int32_t &p1) { i32 = p1; }; // COMPLIANT + [](const std::int32_t &p1) { take_i32(p1); }; // COMPLIANT + [](const std::int32_t &p1) { const int &l1 = p1; }; // COMPLIANT + [](const std::int32_t &p1) { take_cref(p1); }; // COMPLIANT + [](const std::int32_t *p1) { cptr = p1; }; // COMPLIANT + [](const std::int32_t *p1) { take_cptr(p1); }; // COMPLIANT + [](cpi32 p1) { const std::int32_t *const l1 = p1; }; // COMPLIANT + [](cpi32 p1) { take_cptrc(p1); }; // COMPLIANT + [](cri32 p1) { cptr = &p1; }; // COMPLIANT + [](cri32 p1) { take_cptr(&p1); }; // COMPLIANT + [](cri32 p1) { const std::int32_t *const l1 = &p1; }; // COMPLIANT + [](cri32 p1) { take_cptrc(&p1); }; // COMPLIANT + [](cpi32 p1) -> std::int32_t { return *p1; }; // COMPLIANT + [](cpi32 p1) -> const std::int32_t & { return *p1; }; // COMPLIANT + [](cpi32 p1) -> const std::int32_t * { return p1; }; // COMPLIANT + [](cpi32 p1) -> const std::int32_t *const { return p1; }; // COMPLIANT + [](cri32 p1) -> std::int32_t { return p1; }; // COMPLIANT + [](cri32 p1) -> const std::int32_t & { return p1; }; // COMPLIANT + [](cri32 p1) -> const std::int32_t * { return &p1; }; // COMPLIANT + [](cri32 p1) -> const std::int32_t *const { return &p1; }; // COMPLIANT + + // Non pointer compliant cases are not compliant for `int32_t *const`. + using pi32c = std::int32_t *const; + + [](std::int32_t *const p1) { i32 = *p1; }; // NON_COMPLIANT + [](std::int32_t *const p1) { take_i32(*p1); }; // NON_COMPLIANT + [](std::int32_t *const p1) { const int &l1 = *p1; }; // NON_COMPLIANT + [](std::int32_t *const p1) { take_cref(*p1); }; // NON_COMPLIANT + [](std::int32_t *const p1) { cptr = p1; }; // NON_COMPLIANT + [](std::int32_t *const p1) { take_cptr(p1); }; // NON_COMPLIANT + [](pi32c p1) { const std::int32_t *const l1 = p1; }; // NON_COMPLIANT + [](pi32c p1) { take_cptrc(p1); }; // NON_COMPLIANT + [](pi32c p1) -> std::int32_t { return *p1; }; // NON_COMPLIANT + [](pi32c p1) -> const std::int32_t & { return *p1; }; // NON_COMPLIANT + [](pi32c p1) -> const std::int32_t * { return p1; }; // NON_COMPLIANT + [](pi32c p1) -> const std::int32_t *const { return p1; }; // NON_COMPLIANT +} + +void f5(std::int32_t *p1, // NON_COMPLIANT -- pointer modified + std::int32_t *p2, // COMPLIANT -- pointee modified + std::int32_t &p3, // COMPLIANT -- reference modified + std::int32_t *p4, // NON_COMPLIANT -- pointer assigned UNHANDLED + std::int32_t *p5, // COMPLIANT -- pointee assigned + std::int32_t &p6, // COMPLIANT -- assigned + const std::int32_t *p7, // COMPLIANT + const std::int32_t &p8, // COMPLIANT + std::int32_t *p9, // NON_COMPLIANT + std::int32_t &p10, // NON_COMPLIANT + std::int32_t *p11, // COMPLIANT + std::int32_t *p12, // NON_COMPLIANT -- unused + std::int32_t **p13, // COMPLIANT + std::int32_t **p14, // COMPLIANT + std::int32_t **p15, // COMPLIANT + std::int32_t **p16 // COMPLIANT +) { + p1++; + (*p2)++; + p3++; + p4 += 0; + *p5 *= 0; + p6 /= 0; + p7++; + if (p8) { + } + p9 ? true : false; + while (p10) { + } + p11[0] = 0; + // p12 + p13[0] = p1; + p14[0][0] = 0; + (*p15)[0] = 0; + *(p16[0]) = 0; +} + +struct S { + std::int32_t m1; +}; + +void f6(S *p1, // COMPLIANT + S *p2, // NON_COMPLIANT + S *p3 // COMPLIANT UNHANDLED +) { + p1->m1 = 1; + std::int32_t l1 = p2->m1; + std::int32_t &l2 = p3->m1; +} + +void f7(std::int32_t *p1, // COMPLIANT UNHANDLED + std::int32_t *p2, // COMPLIANT + std::int32_t *p3, // NON_COMPLIANT + std::int32_t *p4 // NON_COMPLIANT +) { + using pi32 = std::int32_t *; + using cpi32 = const std::int32_t *; + using ci32 = const std::int32_t; + + pi32 *l1 = &p1; // pointer to pointer to non-const + pi32 &l2 = p2; // reference to pointer to non-const + cpi32 *l3 = &p3; // pointer to pointer to const + const cpi32 &l4 = p4; // (const) reference to pointer to const + // cpi32 &l4 = p4; -- does not compile, non-const lvalues cannot involve a + // const cast from *i32 to const i32* +} + +int main(int argc, char *argv[]); // COMPLIANT - main is excluded +void f8(std::int32_t *p1, std::int32_t &p2); // COMPLIANT - no body to analyze +void f9(std::int32_t *p1, std::int32_t &p2) = delete; // COMPLIANT - deleted +void f10(void *l1) {} // COMPLIANT - void pointer excluded + +class Base { +public: + virtual void f(std::int32_t *p1, std::int32_t &p2); // COMPLIANT +}; + +class Derived : public Base { +public: + void f(std::int32_t *p1, std::int32_t &p2) override; // COMPLIANT +}; + +template struct A { + void m1(T &p1, T *p2) {} // COMPLIANT - in template scope + + void m2() { + auto lambda = [](std::int32_t &l2) { + }; // COMPLIANT - lambda in template scope + } +}; + +template void f11(T &l1) {} // COMPLIANT - function template \ No newline at end of file diff --git a/rule_packages/cpp/Declarations3.json b/rule_packages/cpp/Declarations3.json new file mode 100644 index 0000000000..7736f0b1ab --- /dev/null +++ b/rule_packages/cpp/Declarations3.json @@ -0,0 +1,26 @@ +{ + "MISRA-C++-2023": { + "RULE-10-1-1": { + "properties": { + "enforcement": "decidable", + "obligation": "advisory" + }, + "queries": [ + { + "description": "Pointer or lvalue reference parameters that do not modify the target object should be const-qualified to accurately reflect function behavior and prevent unintended modifications.", + "kind": "problem", + "name": "The target type of a pointer or lvalue reference parameter should be const-qualified appropriately", + "precision": "high", + "severity": "warning", + "short_name": "PointerOrRefParamNotConst", + "tags": [ + "maintainability", + "readability", + "scope/single-translation-unit" + ] + } + ], + "title": "The target type of a pointer or lvalue reference parameter should be const-qualified appropriately" + } + } +} \ No newline at end of file diff --git a/rules.csv b/rules.csv index 172087714d..683326a6c3 100644 --- a/rules.csv +++ b/rules.csv @@ -915,7 +915,7 @@ cpp,MISRA-C++-2023,RULE-9-6-3,Yes,Required,Decidable,Single Translation Unit,The cpp,MISRA-C++-2023,RULE-9-6-4,Yes,Required,Undecidable,System,A function declared with the [[noreturn]] attribute shall not return,MSC53-CPP,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-9-6-5,Yes,Required,Decidable,Single Translation Unit,A function with non-void return type shall return a value on all paths,MSC52-CPP,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-10-0-1,Yes,Advisory,Decidable,Single Translation Unit,A declaration should not declare more than one variable or member variable,M8-0-1,ImportMisra23,Import, -cpp,MISRA-C++-2023,RULE-10-1-1,Yes,Advisory,Decidable,Single Translation Unit,The target type of a pointer or lvalue reference parameter should be const-qualified appropriately,RULE-8-13,Declarations2,Hard, +cpp,MISRA-C++-2023,RULE-10-1-1,Yes,Advisory,Decidable,Single Translation Unit,The target type of a pointer or lvalue reference parameter should be const-qualified appropriately,RULE-8-13,Declarations3,Hard, cpp,MISRA-C++-2023,RULE-10-1-2,Yes,Required,Decidable,Single Translation Unit,The volatile qualifier shall be used appropriately,,Declarations2,Easy, cpp,MISRA-C++-2023,RULE-10-2-1,Yes,Required,Decidable,Single Translation Unit,An enumeration shall be defined with an explicit underlying type,A7-2-2,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-10-2-2,Yes,Advisory,Decidable,Single Translation Unit,Unscoped enumerations should not be declared,A7-2-3,Banned,Easy, From 5facdd529ee0105191e78e31810350989f00a888 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Thu, 2 Apr 2026 19:26:47 -0700 Subject: [PATCH 02/10] First draft that seems potentially complete. --- .../RULE-10-1-1/PointerOrRefParamNotConst.ql | 120 +++++++++++------ .../PointerOrRefParamNotConst.expected | 122 ++++++++---------- cpp/misra/test/rules/RULE-10-1-1/test.cpp | 28 ++-- 3 files changed, 146 insertions(+), 124 deletions(-) diff --git a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql index d725f38255..47bace3d2e 100644 --- a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql +++ b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql @@ -25,21 +25,9 @@ import codingstandards.cpp.alertreporting.HoldsForAllCopies * Holds if the function is in a template scope and should be excluded. */ predicate isInTemplateScope(Function f) { - // Function templates f.isFromTemplateInstantiation(_) or - f instanceof TemplateFunction - or - // Functions declared within the scope of a template class - exists(TemplateClass tc | f.getDeclaringType() = tc) - or - f.getDeclaringType().isFromTemplateInstantiation(_) - or - // Lambdas within template scope - exists(LambdaExpression le | - le.getLambdaFunction() = f and - isInTemplateScope(le.getEnclosingFunction()) - ) + f.isFromUninstantiatedTemplate(_) } /** @@ -96,6 +84,9 @@ class PointerLikeType extends Type { predicate pointsToNonConst() { not innerType.isConst() } } +/** + * A `Parameter` whose type is a `PointerLikeType` such as a pointer or reference. + */ class PointerLikeParam extends Parameter { PointerLikeType pointerLikeType; @@ -107,6 +98,28 @@ class PointerLikeParam extends Parameter { not pointerLikeType.getInnerType() instanceof VoidType } + /** + * Get the pointer like type of this parameter. + */ + PointerLikeType getPointerLikeType() { result = pointerLikeType } + + /** + * Get usages of this parameter that maintain pointer-like semantics -- typically this means + * either a normal access, or switching between pointers and reference semantics. + * + * Examples of accesses with pointer-like semantics include: + * - `ref` in `int &x = ref`, or `&ref` in `int *x = &ref`; + * - `ptr` in `int *x = ptr`, or `*ptr` in `int &x = *ptr`; + * + * In the above examples, we can still access the value pointed to by `ref` or `ptr` through the + * expression. + * + * Examples of non-pointer-like semantics include: + * - `ref` in `int x = ref` and `*ptr` in `int x = *ptr`; + * + * In the above examples, the value pointed to by `ref` or `ptr` is copied and the expression + * refers to a new/different object. + */ Expr getAPointerLikeAccess() { result = this.getAnAccess() or @@ -121,17 +134,40 @@ class PointerLikeParam extends Parameter { } } -query predicate test( - PointerLikeParam param, Expr ptrLikeAccess, Type argtype, Type innerType, string explain -) { - ptrLikeAccess = param.getAPointerLikeAccess() and - exists(FunctionCall fc | - fc.getArgument(0) = ptrLikeAccess and - argtype = fc.getTarget().getParameter(0).getType() and - argtype.(PointerLikeType).pointsToNonConst() and - innerType = argtype.(PointerLikeType).getInnerType() - ) and - explain = argtype.explain() +/** + * A `VariableEffect` whose target variable is a `PointerLikeParam`. + * + * Examples of pointer-like effects on a pointer-like parameter `p` would include `p = ...`, `++p`, + * `*p = ...`, and `++*p`, etc. + */ +class PointerLikeEffect extends VariableEffect { + PointerLikeParam param; + + PointerLikeEffect() { param = this.getTarget() } + + /** + * Holds if this effect modifies the pointed-to or referred-to object. + * + * For example, `*p = 0` modifies the inner type if `p` is a pointer, and `p = 0` affects the + * inner type if `p` is a reference. + */ + predicate affectsInnerType() { + if param.getPointerLikeType() instanceof ReferenceType + then affectsOuterType() + else not affectsOuterType() + } + + /** + * Holds if this effect modifies the pointer or reference itself. + * + * For example, `p = ...` and `++p` modify the outer type, whether that type is a pointer or + * reference, while `*p = 0` does not modify the outer type. + */ + predicate affectsOuterType() { + this.(Assignment).getLValue() = param.getAnAccess() + or + this.(CrementOperation).getOperand() = param.getAnAccess() + } } /** @@ -158,17 +194,10 @@ class NonConstParam extends PointerLikeParam { not this.getFunction().hasGlobalName("main") and // Exclude deleted functions not this.getFunction().isDeleted() and - // Exclude any parameter whose underlying data is modified (VariableEffect) - not exists(VariableEffect effect | + // Exclude any parameter whose underlying data is modified + not exists(PointerLikeEffect effect | effect.getTarget() = this and - ( - // For reference types, any effect is a target modification - pointerLikeType.getOuterType() instanceof ReferenceType - or - // For pointer types, exclude effects that only modify the pointer itself - not effect.(AssignExpr).getLValue() = this.getAnAccess() and - not effect.(CrementOperation).getOperand() = this.getAnAccess() - ) + effect.affectsInnerType() ) and // Exclude parameters passed as arguments to functions taking non-const pointer/ref params not exists(FunctionCall fc, int i | @@ -183,19 +212,30 @@ class NonConstParam extends PointerLikeParam { ) and // Exclude parameters assigned to a non-const pointer/reference alias not exists(Variable v | - v.getAnAssignedValue() = this.getAnAccess() and + v.getAnAssignedValue() = this.getAPointerLikeAccess() and v.getType().(PointerLikeType).pointsToNonConst() ) and // Exclude parameters returned as non-const pointer/reference not exists(ReturnStmt ret | - ret.getExpr() = this.getAnAccess() and + ret.getExpr() = this.getAPointerLikeAccess() and ret.getEnclosingFunction().getType().(PointerLikeType).pointsToNonConst() + ) and + not exists(FieldAccess fa | + fa.getQualifier() = [this.getAPointerLikeAccess(), this.getAnAccess()] and + fa.isLValueCategory() + ) and + not exists(AddressOfExpr addrOf | + // exclude pointer to pointer and reference to pointer cases. + addrOf.getOperand() = this.getAPointerLikeAccess() and + addrOf.getType().(PointerLikeType).getInnerType() instanceof PointerLikeType ) } } -from NonConstParam param -where not isExcluded(param, Declarations3Package::pointerOrRefParamNotConstQuery()) +from NonConstParam param, Type innerType +where + not isExcluded(param, Declarations3Package::pointerOrRefParamNotConstQuery()) and + innerType = param.getPointerLikeType().getInnerType() select param, - "Parameter '" + param.getName() + - "' points/refers to a non-const-qualified type but does not modify the target object." + "Parameter '" + param.getName() + "' points/refers to a non-const type '" + innerType.toString() + + "' but does not modify the target object." diff --git a/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected b/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected index f59c23c14c..a63ffebedd 100644 --- a/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected +++ b/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected @@ -1,70 +1,52 @@ -test -| test.cpp:44:20:44:21 | p1 | test.cpp:44:35:44:37 | * ... | file://:0:0:0:0 | int32_t & | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | reference to {typedef {signed int} as "int32_t"} | -| test.cpp:53:20:53:21 | p1 | test.cpp:53:35:53:36 | p1 | file://:0:0:0:0 | int32_t & | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | reference to {typedef {signed int} as "int32_t"} | -| test.cpp:59:20:59:21 | p1 | test.cpp:59:35:59:36 | p1 | file://:0:0:0:0 | int32_t * | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | pointer to {typedef {signed int} as "int32_t"} | -| test.cpp:65:20:65:21 | p1 | test.cpp:65:36:65:37 | p1 | file://:0:0:0:0 | int32_t *const | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | const {pointer to {typedef {signed int} as "int32_t"}} | -| test.cpp:69:20:69:21 | p1 | test.cpp:69:35:69:37 | & ... | file://:0:0:0:0 | int32_t * | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | pointer to {typedef {signed int} as "int32_t"} | -| test.cpp:75:20:75:21 | p1 | test.cpp:75:36:75:38 | & ... | file://:0:0:0:0 | int32_t *const | file:///Users/michaelrfairhurst/projects/codeql-coding-standards/cpp/common/test/includes/standard-library/stdint.h:8:20:8:26 | int32_t | const {pointer to {typedef {signed int} as "int32_t"}} | -#select -| test.cpp:4:22:4:23 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:7:28:7:29 | p4 | Parameter 'p4' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:8:21:8:22 | p5 | Parameter 'p5' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:19:36:19:37 | l2 | Parameter 'l2' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:40:20:40:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:41:20:41:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:42:20:42:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:43:20:43:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:45:20:45:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:46:20:46:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:50:20:50:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:51:20:51:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:54:20:54:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:55:20:55:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:60:20:60:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:61:20:61:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:62:20:62:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:63:20:63:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:68:20:68:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:70:20:70:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:71:20:71:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:72:20:72:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:73:20:73:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:74:20:74:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:78:20:78:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:79:20:79:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:80:20:80:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:82:20:82:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:84:20:84:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:89:20:89:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:91:20:91:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:92:20:92:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:93:20:93:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:94:20:94:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:95:20:95:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:100:20:100:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:102:20:102:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:103:20:103:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:104:20:104:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:105:20:105:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:106:20:106:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:142:26:142:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:143:26:143:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:144:26:144:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:145:26:145:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:146:26:146:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:147:26:147:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:148:12:148:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:149:12:149:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:150:12:150:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:151:12:151:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:152:12:152:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:153:12:153:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:156:23:156:24 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:164:23:164:24 | p9 | Parameter 'p9' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:165:23:165:25 | p10 | Parameter 'p10' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:167:23:167:25 | p12 | Parameter 'p12' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:198:12:198:13 | p2 | Parameter 'p2' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:199:12:199:13 | p3 | Parameter 'p3' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:206:23:206:24 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:208:23:208:24 | p3 | Parameter 'p3' points/refers to a non-const-qualified type but does not modify the target object. | -| test.cpp:209:23:209:24 | p4 | Parameter 'p4' points/refers to a non-const-qualified type but does not modify the target object. | +| test.cpp:4:22:4:23 | p1 | Parameter 'p1' points/refers to a non-const type 'int8_t' but does not modify the target object. | +| test.cpp:7:28:7:29 | p4 | Parameter 'p4' points/refers to a non-const type 'int8_t' but does not modify the target object. | +| test.cpp:8:21:8:22 | p5 | Parameter 'p5' points/refers to a non-const type 'int8_t' but does not modify the target object. | +| test.cpp:19:36:19:37 | l2 | Parameter 'l2' points/refers to a non-const type 'vector>' but does not modify the target object. | +| test.cpp:40:20:40:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:41:20:41:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:42:20:42:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:45:20:45:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:46:20:46:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:50:20:50:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:51:20:51:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:54:20:54:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:55:20:55:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:60:20:60:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:61:20:61:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:62:20:62:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:63:20:63:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:70:20:70:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:71:20:71:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:72:20:72:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:73:20:73:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:78:20:78:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:80:20:80:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:82:20:82:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:84:20:84:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:89:20:89:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:91:20:91:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:93:20:93:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:95:20:95:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:100:20:100:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:102:20:102:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:104:20:104:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:106:20:106:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:142:26:142:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:143:26:143:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:144:26:144:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:145:26:145:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:146:26:146:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:147:26:147:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:148:12:148:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:149:12:149:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:150:12:150:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:151:12:151:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:152:12:152:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:153:12:153:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:156:23:156:24 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:159:23:159:24 | p4 | Parameter 'p4' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:164:23:164:24 | p9 | Parameter 'p9' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:165:23:165:25 | p10 | Parameter 'p10' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:167:23:167:25 | p12 | Parameter 'p12' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:198:12:198:13 | p2 | Parameter 'p2' points/refers to a non-const type 'S' but does not modify the target object. | +| test.cpp:209:23:209:24 | p4 | Parameter 'p4' points/refers to a non-const type 'int32_t' but does not modify the target object. | diff --git a/cpp/misra/test/rules/RULE-10-1-1/test.cpp b/cpp/misra/test/rules/RULE-10-1-1/test.cpp index 73b49bacba..1c6fbd203f 100644 --- a/cpp/misra/test/rules/RULE-10-1-1/test.cpp +++ b/cpp/misra/test/rules/RULE-10-1-1/test.cpp @@ -37,16 +37,16 @@ void take_cref(const std::int32_t &l1); void f4() { // Pointers used as values [](std::int32_t *p1) { *p1 = 0; }; // COMPLIANT - [](std::int32_t *p1) { p1 = nullptr; }; // NON_COMPLIANT UNHANDLED + [](std::int32_t *p1) { p1 = nullptr; }; // NON_COMPLIANT [](std::int32_t *p1) { i32 = *p1; }; // NON_COMPLIANT [](std::int32_t *p1) { take_i32(*p1); }; // NON_COMPLIANT - [](std::int32_t *p1) { ref = *p1; }; // COMPLIANT UNHANDLED + [](std::int32_t *p1) { ref = *p1; }; // COMPLIANT [](std::int32_t *p1) { take_ref(*p1); }; // COMPLIANT [](std::int32_t *p1) { const int &l1 = *p1; }; // NON_COMPLIANT [](std::int32_t *p1) { take_cref(*p1); }; // NON_COMPLIANT // References used as values - [](std::int32_t &p1) { p1 = 0; }; // NON_COMPLIANT UNHANDLED + [](std::int32_t &p1) { p1 = 0; }; // COMPLIANT [](std::int32_t &p1) { i32 = p1; }; // NON_COMPLIANT [](std::int32_t &p1) { take_i32(p1); }; // NON_COMPLIANT [](std::int32_t &p1) { ref = p1; }; // COMPLIANT @@ -65,18 +65,18 @@ void f4() { [](std::int32_t *p1) { take_ptrc(p1); }; // COMPLIANT // Taking addresses of references parameter - [](std::int32_t &p1) { ptr = &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) { ptr = &p1; }; // COMPLIANT [](std::int32_t &p1) { take_ptr(&p1); }; // COMPLIANT [](std::int32_t &p1) { cptr = &p1; }; // NON_COMPLIANT [](std::int32_t &p1) { take_cptr(&p1); }; // NON_COMPLIANT [](std::int32_t &p1) { const std::int32_t *const l1 = &p1; }; // NON_COMPLIANT [](std::int32_t &p1) { take_cptrc(&p1); }; // NON_COMPLIANT - [](std::int32_t &p1) { std::int32_t *const l1 = &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) { std::int32_t *const l1 = &p1; }; // COMPLIANT [](std::int32_t &p1) { take_ptrc(&p1); }; // COMPLIANT // Returning from pointer parameters [](std::int32_t *p1) -> std::int32_t { return *p1; }; // NON_COMPLIANT - [](std::int32_t *p1) -> std::int32_t & { return *p1; }; // COMPLIANT UNHANDLED + [](std::int32_t *p1) -> std::int32_t & { return *p1; }; // COMPLIANT [](std::int32_t *p1) -> const std::int32_t & { return *p1; }; // NON_COMPLIANT [](std::int32_t *p1) -> std::int32_t * { return p1; }; // COMPLIANT [](std::int32_t *p1) -> const std::int32_t * { return p1; }; // NON_COMPLIANT @@ -89,9 +89,9 @@ void f4() { [](std::int32_t &p1) -> std::int32_t { return p1; }; // NON_COMPLIANT [](std::int32_t &p1) -> std::int32_t & { return p1; }; // COMPLIANT [](std::int32_t &p1) -> const std::int32_t & { return p1; }; // NON_COMPLIANT - [](std::int32_t &p1) -> std::int32_t * { return &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) -> std::int32_t * { return &p1; }; // COMPLIANT [](std::int32_t &p1) -> const std::int32_t * { return &p1; }; // NON_COMPLIANT - [](std::int32_t &p1) -> std::int32_t *const { return &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) -> std::int32_t *const { return &p1; }; // COMPLIANT [](std::int32_t &p1) -> const std::int32_t *const { return &p1; }; // NON_COMPLIANT @@ -100,9 +100,9 @@ void f4() { [](std::int32_t &p1) -> std::int32_t { return p1; }; // NON_COMPLIANT [](std::int32_t &p1) -> std::int32_t & { return p1; }; // COMPLIANT [](std::int32_t &p1) -> const std::int32_t & { return p1; }; // NON_COMPLIANT - [](std::int32_t &p1) -> std::int32_t * { return &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) -> std::int32_t * { return &p1; }; // COMPLIANT [](std::int32_t &p1) -> const std::int32_t * { return &p1; }; // NON_COMPLIANT - [](std::int32_t &p1) -> std::int32_t *const { return &p1; }; // COMPLIANT UNHANDLED + [](std::int32_t &p1) -> std::int32_t *const { return &p1; }; // COMPLIANT [](std::int32_t &p1) -> const std::int32_t *const { return &p1; }; // NON_COMPLIANT @@ -156,7 +156,7 @@ void f4() { void f5(std::int32_t *p1, // NON_COMPLIANT -- pointer modified std::int32_t *p2, // COMPLIANT -- pointee modified std::int32_t &p3, // COMPLIANT -- reference modified - std::int32_t *p4, // NON_COMPLIANT -- pointer assigned UNHANDLED + std::int32_t *p4, // NON_COMPLIANT -- pointer assigned std::int32_t *p5, // COMPLIANT -- pointee assigned std::int32_t &p6, // COMPLIANT -- assigned const std::int32_t *p7, // COMPLIANT @@ -196,16 +196,16 @@ struct S { void f6(S *p1, // COMPLIANT S *p2, // NON_COMPLIANT - S *p3 // COMPLIANT UNHANDLED + S *p3 // COMPLIANT ) { p1->m1 = 1; std::int32_t l1 = p2->m1; std::int32_t &l2 = p3->m1; } -void f7(std::int32_t *p1, // COMPLIANT UNHANDLED +void f7(std::int32_t *p1, // COMPLIANT std::int32_t *p2, // COMPLIANT - std::int32_t *p3, // NON_COMPLIANT + std::int32_t *p3, // NON_COMPLIANT[False negative] std::int32_t *p4 // NON_COMPLIANT ) { using pi32 = std::int32_t *; From 3d93c8e4bc90579ec0262479f0e632a95f65ee45 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 3 Apr 2026 16:35:25 -0700 Subject: [PATCH 03/10] Finalize as Declaration6 - rule 10-1-1 properly const qualify refs & pointers. --- .../{Declarations3.qll => Declarations6.qll} | 10 +- .../cpp/exclusions/cpp/RuleMetadata.qll | 6 +- .../RULE-10-1-1/PointerOrRefParamNotConst.ql | 48 ++++++-- .../PointerOrRefParamNotConst.expected | 104 +++++++++--------- cpp/misra/test/rules/RULE-10-1-1/test.cpp | 74 ++++++------- ...{Declarations3.json => Declarations6.json} | 0 6 files changed, 136 insertions(+), 106 deletions(-) rename cpp/common/src/codingstandards/cpp/exclusions/cpp/{Declarations3.qll => Declarations6.qll} (67%) rename rule_packages/cpp/{Declarations3.json => Declarations6.json} (100%) diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations3.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations6.qll similarity index 67% rename from cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations3.qll rename to cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations6.qll index 47d0d1bf85..cc2ffb53c3 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations3.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations6.qll @@ -3,12 +3,12 @@ import cpp import RuleMetadata import codingstandards.cpp.exclusions.RuleMetadata -newtype Declarations3Query = TPointerOrRefParamNotConstQuery() +newtype Declarations6Query = TPointerOrRefParamNotConstQuery() -predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleId, string category) { +predicate isDeclarations6QueryMetadata(Query query, string queryId, string ruleId, string category) { query = // `Query` instance for the `pointerOrRefParamNotConst` query - Declarations3Package::pointerOrRefParamNotConstQuery() and + Declarations6Package::pointerOrRefParamNotConstQuery() and queryId = // `@id` for the `pointerOrRefParamNotConst` query "cpp/misra/pointer-or-ref-param-not-const" and @@ -16,11 +16,11 @@ predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleI category = "advisory" } -module Declarations3Package { +module Declarations6Package { Query pointerOrRefParamNotConstQuery() { //autogenerate `Query` type result = // `Query` type for `pointerOrRefParamNotConst` query - TQueryCPP(TDeclarations3PackageQuery(TPointerOrRefParamNotConstQuery())) + TQueryCPP(TDeclarations6PackageQuery(TPointerOrRefParamNotConstQuery())) } } diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll index 999882d81b..9b0971b8c0 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll @@ -28,7 +28,7 @@ import DeadCode8 import DeadCode9 import Declarations import Declarations1 -import Declarations3 +import Declarations6 import ExceptionSafety import Exceptions1 import Exceptions2 @@ -120,7 +120,7 @@ newtype TCPPQuery = TDeadCode9PackageQuery(DeadCode9Query q) or TDeclarationsPackageQuery(DeclarationsQuery q) or TDeclarations1PackageQuery(Declarations1Query q) or - TDeclarations3PackageQuery(Declarations3Query q) or + TDeclarations6PackageQuery(Declarations6Query q) or TExceptionSafetyPackageQuery(ExceptionSafetyQuery q) or TExceptions1PackageQuery(Exceptions1Query q) or TExceptions2PackageQuery(Exceptions2Query q) or @@ -212,7 +212,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat isDeadCode9QueryMetadata(query, queryId, ruleId, category) or isDeclarationsQueryMetadata(query, queryId, ruleId, category) or isDeclarations1QueryMetadata(query, queryId, ruleId, category) or - isDeclarations3QueryMetadata(query, queryId, ruleId, category) or + isDeclarations6QueryMetadata(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-10-1-1/PointerOrRefParamNotConst.ql b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql index 47bace3d2e..9b0d1f5c43 100644 --- a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql +++ b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql @@ -18,6 +18,7 @@ import cpp import codingstandards.cpp.misra import codingstandards.cpp.types.Pointers +import codingstandards.cpp.Call import codingstandards.cpp.SideEffect import codingstandards.cpp.alertreporting.HoldsForAllCopies @@ -94,8 +95,7 @@ class PointerLikeParam extends Parameter { pointerLikeType = this.getType() and not pointerLikeType.pointsToConst() and // Exclude pointers to non-object types - not pointerLikeType.getInnerType() instanceof RoutineType and - not pointerLikeType.getInnerType() instanceof VoidType + not pointerLikeType.getInnerType() instanceof RoutineType } /** @@ -134,6 +134,24 @@ class PointerLikeParam extends Parameter { } } +predicate test(Assignment a, Field f, Parameter p, string n) { + a.getLValue() = f.getAnAccess() and + a.getRValue() = p.getAnAccess() and + f.getName() = "planes" and + n = p.getFunction().getName() and + a.getFile().getBaseName() = "matrix_iterator.cpp" +} + +predicate test2(Parameter p) { + p.getName() = ["planes", "_planes"] and + p.getFunction().getName() = "init" +} + +predicate test3(Function f, int num) { + f.getName() = "init" and + num = strictcount(Parameter p | p.getFunction() = f and p.getName() = ["planes", "_planes"]) +} + /** * A `VariableEffect` whose target variable is a `PointerLikeParam`. * @@ -176,6 +194,7 @@ class PointerLikeEffect extends VariableEffect { class NonConstParam extends PointerLikeParam { NonConstParam() { not pointerLikeType.pointsToConst() and + not pointerLikeType.getInnerType() instanceof VoidType and // Ignore parameters in functions without bodies exists(this.getFunction().getBlock()) and // Ignore unnamed parameters @@ -199,14 +218,14 @@ class NonConstParam extends PointerLikeParam { effect.getTarget() = this and effect.affectsInnerType() ) and - // Exclude parameters passed as arguments to functions taking non-const pointer/ref params - not exists(FunctionCall fc, int i | - fc.getArgument(i) = this.getAPointerLikeAccess() and - fc.getTarget().getParameter(i).getType().(PointerLikeType).pointsToNonConst() + // Exclude parameters passed as arguments to non-const pointer/ref params + not exists(CallArgumentExpr arg | + arg = this.getAPointerLikeAccess() and + arg.getParamType().(PointerLikeType).pointsToNonConst() ) and // Exclude parameters used as qualifier for a non-const member function not exists(FunctionCall fc | - fc.getQualifier() = this.getAnAccess() and + fc.getQualifier() = [this.getAnAccess(), this.getAPointerLikeAccess()] and not fc.getTarget().hasSpecifier("const") and not fc.getTarget().isStatic() ) and @@ -228,6 +247,10 @@ class NonConstParam extends PointerLikeParam { // exclude pointer to pointer and reference to pointer cases. addrOf.getOperand() = this.getAPointerLikeAccess() and addrOf.getType().(PointerLikeType).getInnerType() instanceof PointerLikeType + ) and + not exists(PointerArithmeticOperation pointerManip | + pointerManip.getAnOperand() = this.getAPointerLikeAccess() and + pointerManip.getType().(PointerLikeType).pointsToNonConst() ) } } @@ -235,7 +258,14 @@ class NonConstParam extends PointerLikeParam { from NonConstParam param, Type innerType where not isExcluded(param, Declarations3Package::pointerOrRefParamNotConstQuery()) and - innerType = param.getPointerLikeType().getInnerType() + innerType = param.getPointerLikeType().getInnerType() and + not param.isAffectedByMacro() and + // Exclude functions with copied parameters which leads to wrong results. + count(Parameter p | + p.getFunction() = param.getFunction() and + p.getIndex() = param.getIndex() + ) = 1 select param, "Parameter '" + param.getName() + "' points/refers to a non-const type '" + innerType.toString() + - "' but does not modify the target object." + "' but does not modify the target object in the $@.", param.getFunction().getDefinition(), + "function definition" diff --git a/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected b/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected index a63ffebedd..85b24a4ab6 100644 --- a/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected +++ b/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected @@ -1,52 +1,52 @@ -| test.cpp:4:22:4:23 | p1 | Parameter 'p1' points/refers to a non-const type 'int8_t' but does not modify the target object. | -| test.cpp:7:28:7:29 | p4 | Parameter 'p4' points/refers to a non-const type 'int8_t' but does not modify the target object. | -| test.cpp:8:21:8:22 | p5 | Parameter 'p5' points/refers to a non-const type 'int8_t' but does not modify the target object. | -| test.cpp:19:36:19:37 | l2 | Parameter 'l2' points/refers to a non-const type 'vector>' but does not modify the target object. | -| test.cpp:40:20:40:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:41:20:41:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:42:20:42:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:45:20:45:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:46:20:46:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:50:20:50:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:51:20:51:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:54:20:54:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:55:20:55:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:60:20:60:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:61:20:61:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:62:20:62:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:63:20:63:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:70:20:70:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:71:20:71:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:72:20:72:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:73:20:73:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:78:20:78:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:80:20:80:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:82:20:82:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:84:20:84:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:89:20:89:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:91:20:91:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:93:20:93:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:95:20:95:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:100:20:100:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:102:20:102:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:104:20:104:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:106:20:106:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:142:26:142:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:143:26:143:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:144:26:144:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:145:26:145:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:146:26:146:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:147:26:147:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:148:12:148:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:149:12:149:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:150:12:150:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:151:12:151:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:152:12:152:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:153:12:153:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:156:23:156:24 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:159:23:159:24 | p4 | Parameter 'p4' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:164:23:164:24 | p9 | Parameter 'p9' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:165:23:165:25 | p10 | Parameter 'p10' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:167:23:167:25 | p12 | Parameter 'p12' points/refers to a non-const type 'int32_t' but does not modify the target object. | -| test.cpp:198:12:198:13 | p2 | Parameter 'p2' points/refers to a non-const type 'S' but does not modify the target object. | -| test.cpp:209:23:209:24 | p4 | Parameter 'p4' points/refers to a non-const type 'int32_t' but does not modify the target object. | +| test.cpp:4:22:4:23 | p1 | Parameter 'p1' points/refers to a non-const type 'int8_t' but does not modify the target object in the $@. | test.cpp:4:6:4:7 | definition of f1 | function definition | +| test.cpp:7:28:7:29 | p4 | Parameter 'p4' points/refers to a non-const type 'int8_t' but does not modify the target object in the $@. | test.cpp:4:6:4:7 | definition of f1 | function definition | +| test.cpp:8:21:8:22 | p5 | Parameter 'p5' points/refers to a non-const type 'int8_t' but does not modify the target object in the $@. | test.cpp:4:6:4:7 | definition of f1 | function definition | +| test.cpp:19:36:19:37 | l2 | Parameter 'l2' points/refers to a non-const type 'vector>' but does not modify the target object in the $@. | test.cpp:18:6:18:7 | definition of f3 | function definition | +| test.cpp:40:20:40:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:40:5:40:5 | definition of operator() | function definition | +| test.cpp:41:20:41:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:41:5:41:5 | definition of operator() | function definition | +| test.cpp:42:20:42:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:42:5:42:5 | definition of operator() | function definition | +| test.cpp:45:20:45:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:45:5:45:5 | definition of operator() | function definition | +| test.cpp:46:20:46:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:46:5:46:5 | definition of operator() | function definition | +| test.cpp:50:20:50:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:50:5:50:5 | definition of operator() | function definition | +| test.cpp:51:20:51:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:51:5:51:5 | definition of operator() | function definition | +| test.cpp:54:20:54:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:54:5:54:5 | definition of operator() | function definition | +| test.cpp:55:20:55:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:55:5:55:5 | definition of operator() | function definition | +| test.cpp:60:20:60:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:60:5:60:5 | definition of operator() | function definition | +| test.cpp:61:20:61:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:61:5:61:5 | definition of operator() | function definition | +| test.cpp:62:20:62:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:62:5:62:5 | definition of operator() | function definition | +| test.cpp:63:20:63:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:63:5:63:5 | definition of operator() | function definition | +| test.cpp:70:20:70:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:70:5:70:5 | definition of operator() | function definition | +| test.cpp:71:20:71:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:71:5:71:5 | definition of operator() | function definition | +| test.cpp:72:20:72:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:72:5:72:5 | definition of operator() | function definition | +| test.cpp:73:20:73:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:73:5:73:5 | definition of operator() | function definition | +| test.cpp:78:20:78:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:78:5:78:5 | definition of operator() | function definition | +| test.cpp:80:20:80:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:80:5:80:5 | definition of operator() | function definition | +| test.cpp:82:20:82:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:82:5:82:5 | definition of operator() | function definition | +| test.cpp:84:20:84:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:84:5:84:5 | definition of operator() | function definition | +| test.cpp:89:20:89:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:89:5:89:5 | definition of operator() | function definition | +| test.cpp:91:20:91:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:91:5:91:5 | definition of operator() | function definition | +| test.cpp:93:20:93:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:93:5:93:5 | definition of operator() | function definition | +| test.cpp:95:20:95:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:95:5:95:5 | definition of operator() | function definition | +| test.cpp:100:20:100:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:100:5:100:5 | definition of operator() | function definition | +| test.cpp:102:20:102:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:102:5:102:5 | definition of operator() | function definition | +| test.cpp:104:20:104:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:104:5:104:5 | definition of operator() | function definition | +| test.cpp:106:20:106:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:106:5:106:5 | definition of operator() | function definition | +| test.cpp:142:26:142:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:142:5:142:5 | definition of operator() | function definition | +| test.cpp:143:26:143:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:143:5:143:5 | definition of operator() | function definition | +| test.cpp:144:26:144:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:144:5:144:5 | definition of operator() | function definition | +| test.cpp:145:26:145:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:145:5:145:5 | definition of operator() | function definition | +| test.cpp:146:26:146:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:146:5:146:5 | definition of operator() | function definition | +| test.cpp:147:26:147:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:147:5:147:5 | definition of operator() | function definition | +| test.cpp:148:12:148:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:148:5:148:5 | definition of operator() | function definition | +| test.cpp:149:12:149:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:149:5:149:5 | definition of operator() | function definition | +| test.cpp:150:12:150:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:150:5:150:5 | definition of operator() | function definition | +| test.cpp:151:12:151:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:151:5:151:5 | definition of operator() | function definition | +| test.cpp:152:12:152:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:152:5:152:5 | definition of operator() | function definition | +| test.cpp:153:12:153:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:153:5:153:5 | definition of operator() | function definition | +| test.cpp:156:23:156:24 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:156:6:156:7 | definition of f5 | function definition | +| test.cpp:159:23:159:24 | p4 | Parameter 'p4' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:156:6:156:7 | definition of f5 | function definition | +| test.cpp:164:23:164:24 | p9 | Parameter 'p9' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:156:6:156:7 | definition of f5 | function definition | +| test.cpp:165:23:165:25 | p10 | Parameter 'p10' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:156:6:156:7 | definition of f5 | function definition | +| test.cpp:167:23:167:25 | p12 | Parameter 'p12' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:156:6:156:7 | definition of f5 | function definition | +| test.cpp:198:12:198:13 | p2 | Parameter 'p2' points/refers to a non-const type 'S' but does not modify the target object in the $@. | test.cpp:197:6:197:7 | definition of f6 | function definition | +| test.cpp:209:23:209:24 | p4 | Parameter 'p4' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:206:6:206:7 | definition of f7 | function definition | diff --git a/cpp/misra/test/rules/RULE-10-1-1/test.cpp b/cpp/misra/test/rules/RULE-10-1-1/test.cpp index 1c6fbd203f..912ec297e2 100644 --- a/cpp/misra/test/rules/RULE-10-1-1/test.cpp +++ b/cpp/misra/test/rules/RULE-10-1-1/test.cpp @@ -80,7 +80,7 @@ void f4() { [](std::int32_t *p1) -> const std::int32_t & { return *p1; }; // NON_COMPLIANT [](std::int32_t *p1) -> std::int32_t * { return p1; }; // COMPLIANT [](std::int32_t *p1) -> const std::int32_t * { return p1; }; // NON_COMPLIANT - [](std::int32_t *p1) -> std::int32_t *const { return p1; }; // COMPLIANT + [](std::int32_t *p1) -> std::int32_t *const { return p1; }; // COMPLIANT [](std::int32_t *p1) -> const std::int32_t *const { return p1; }; // NON_COMPLIANT @@ -91,7 +91,7 @@ void f4() { [](std::int32_t &p1) -> const std::int32_t & { return p1; }; // NON_COMPLIANT [](std::int32_t &p1) -> std::int32_t * { return &p1; }; // COMPLIANT [](std::int32_t &p1) -> const std::int32_t * { return &p1; }; // NON_COMPLIANT - [](std::int32_t &p1) -> std::int32_t *const { return &p1; }; // COMPLIANT + [](std::int32_t &p1) -> std::int32_t *const { return &p1; }; // COMPLIANT [](std::int32_t &p1) -> const std::int32_t *const { return &p1; }; // NON_COMPLIANT @@ -102,7 +102,7 @@ void f4() { [](std::int32_t &p1) -> const std::int32_t & { return p1; }; // NON_COMPLIANT [](std::int32_t &p1) -> std::int32_t * { return &p1; }; // COMPLIANT [](std::int32_t &p1) -> const std::int32_t * { return &p1; }; // NON_COMPLIANT - [](std::int32_t &p1) -> std::int32_t *const { return &p1; }; // COMPLIANT + [](std::int32_t &p1) -> std::int32_t *const { return &p1; }; // COMPLIANT [](std::int32_t &p1) -> const std::int32_t *const { return &p1; }; // NON_COMPLIANT @@ -110,46 +110,46 @@ void f4() { // Non compliant cases are compliant when const using cpi32 = const std::int32_t *; using cri32 = const std::int32_t &; - [](const std::int32_t *p1) { p1 = nullptr; }; // COMPLIANT - [](const std::int32_t *p1) { i32 = *p1; }; // COMPLIANT - [](const std::int32_t *p1) { take_i32(*p1); }; // COMPLIANT - [](const std::int32_t *p1) { const int &l1 = *p1; }; // COMPLIANT - [](const std::int32_t *p1) { take_cref(*p1); }; // COMPLIANT - [](const std::int32_t &p1) { i32 = p1; }; // COMPLIANT - [](const std::int32_t &p1) { take_i32(p1); }; // COMPLIANT - [](const std::int32_t &p1) { const int &l1 = p1; }; // COMPLIANT - [](const std::int32_t &p1) { take_cref(p1); }; // COMPLIANT - [](const std::int32_t *p1) { cptr = p1; }; // COMPLIANT - [](const std::int32_t *p1) { take_cptr(p1); }; // COMPLIANT - [](cpi32 p1) { const std::int32_t *const l1 = p1; }; // COMPLIANT - [](cpi32 p1) { take_cptrc(p1); }; // COMPLIANT - [](cri32 p1) { cptr = &p1; }; // COMPLIANT - [](cri32 p1) { take_cptr(&p1); }; // COMPLIANT - [](cri32 p1) { const std::int32_t *const l1 = &p1; }; // COMPLIANT - [](cri32 p1) { take_cptrc(&p1); }; // COMPLIANT - [](cpi32 p1) -> std::int32_t { return *p1; }; // COMPLIANT - [](cpi32 p1) -> const std::int32_t & { return *p1; }; // COMPLIANT - [](cpi32 p1) -> const std::int32_t * { return p1; }; // COMPLIANT + [](const std::int32_t *p1) { p1 = nullptr; }; // COMPLIANT + [](const std::int32_t *p1) { i32 = *p1; }; // COMPLIANT + [](const std::int32_t *p1) { take_i32(*p1); }; // COMPLIANT + [](const std::int32_t *p1) { const int &l1 = *p1; }; // COMPLIANT + [](const std::int32_t *p1) { take_cref(*p1); }; // COMPLIANT + [](const std::int32_t &p1) { i32 = p1; }; // COMPLIANT + [](const std::int32_t &p1) { take_i32(p1); }; // COMPLIANT + [](const std::int32_t &p1) { const int &l1 = p1; }; // COMPLIANT + [](const std::int32_t &p1) { take_cref(p1); }; // COMPLIANT + [](const std::int32_t *p1) { cptr = p1; }; // COMPLIANT + [](const std::int32_t *p1) { take_cptr(p1); }; // COMPLIANT + [](cpi32 p1) { const std::int32_t *const l1 = p1; }; // COMPLIANT + [](cpi32 p1) { take_cptrc(p1); }; // COMPLIANT + [](cri32 p1) { cptr = &p1; }; // COMPLIANT + [](cri32 p1) { take_cptr(&p1); }; // COMPLIANT + [](cri32 p1) { const std::int32_t *const l1 = &p1; }; // COMPLIANT + [](cri32 p1) { take_cptrc(&p1); }; // COMPLIANT + [](cpi32 p1) -> std::int32_t { return *p1; }; // COMPLIANT + [](cpi32 p1) -> const std::int32_t & { return *p1; }; // COMPLIANT + [](cpi32 p1) -> const std::int32_t * { return p1; }; // COMPLIANT [](cpi32 p1) -> const std::int32_t *const { return p1; }; // COMPLIANT - [](cri32 p1) -> std::int32_t { return p1; }; // COMPLIANT - [](cri32 p1) -> const std::int32_t & { return p1; }; // COMPLIANT - [](cri32 p1) -> const std::int32_t * { return &p1; }; // COMPLIANT + [](cri32 p1) -> std::int32_t { return p1; }; // COMPLIANT + [](cri32 p1) -> const std::int32_t & { return p1; }; // COMPLIANT + [](cri32 p1) -> const std::int32_t * { return &p1; }; // COMPLIANT [](cri32 p1) -> const std::int32_t *const { return &p1; }; // COMPLIANT // Non pointer compliant cases are not compliant for `int32_t *const`. using pi32c = std::int32_t *const; - [](std::int32_t *const p1) { i32 = *p1; }; // NON_COMPLIANT - [](std::int32_t *const p1) { take_i32(*p1); }; // NON_COMPLIANT - [](std::int32_t *const p1) { const int &l1 = *p1; }; // NON_COMPLIANT - [](std::int32_t *const p1) { take_cref(*p1); }; // NON_COMPLIANT - [](std::int32_t *const p1) { cptr = p1; }; // NON_COMPLIANT - [](std::int32_t *const p1) { take_cptr(p1); }; // NON_COMPLIANT - [](pi32c p1) { const std::int32_t *const l1 = p1; }; // NON_COMPLIANT - [](pi32c p1) { take_cptrc(p1); }; // NON_COMPLIANT - [](pi32c p1) -> std::int32_t { return *p1; }; // NON_COMPLIANT - [](pi32c p1) -> const std::int32_t & { return *p1; }; // NON_COMPLIANT - [](pi32c p1) -> const std::int32_t * { return p1; }; // NON_COMPLIANT + [](std::int32_t *const p1) { i32 = *p1; }; // NON_COMPLIANT + [](std::int32_t *const p1) { take_i32(*p1); }; // NON_COMPLIANT + [](std::int32_t *const p1) { const int &l1 = *p1; }; // NON_COMPLIANT + [](std::int32_t *const p1) { take_cref(*p1); }; // NON_COMPLIANT + [](std::int32_t *const p1) { cptr = p1; }; // NON_COMPLIANT + [](std::int32_t *const p1) { take_cptr(p1); }; // NON_COMPLIANT + [](pi32c p1) { const std::int32_t *const l1 = p1; }; // NON_COMPLIANT + [](pi32c p1) { take_cptrc(p1); }; // NON_COMPLIANT + [](pi32c p1) -> std::int32_t { return *p1; }; // NON_COMPLIANT + [](pi32c p1) -> const std::int32_t & { return *p1; }; // NON_COMPLIANT + [](pi32c p1) -> const std::int32_t * { return p1; }; // NON_COMPLIANT [](pi32c p1) -> const std::int32_t *const { return p1; }; // NON_COMPLIANT } diff --git a/rule_packages/cpp/Declarations3.json b/rule_packages/cpp/Declarations6.json similarity index 100% rename from rule_packages/cpp/Declarations3.json rename to rule_packages/cpp/Declarations6.json From 2c9549c04b01e9176450e1cf43fbd9c46d3c1ec4 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 3 Apr 2026 16:38:32 -0700 Subject: [PATCH 04/10] Add Call.qll --- cpp/common/src/codingstandards/cpp/Call.qll | 44 +++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/cpp/common/src/codingstandards/cpp/Call.qll b/cpp/common/src/codingstandards/cpp/Call.qll index 4edbb454a6..dd2bf013f6 100644 --- a/cpp/common/src/codingstandards/cpp/Call.qll +++ b/cpp/common/src/codingstandards/cpp/Call.qll @@ -17,3 +17,47 @@ FunctionType getExprCallFunctionType(ExprCall call) { // Returns a RoutineType result = call.(ExprCall).getChild(-1).getType().(PointerToMemberType).getBaseType() } + +/** + * An `Expr` that is used as an argument to a `Call`, and has helpers to handle with the differences + * between `ExprCall` and `FunctionCall` cases. + */ +class CallArgumentExpr extends Expr { + Call call; + Type paramType; + int argIndex; + + CallArgumentExpr() { + this = call.getArgument(argIndex) and + ( + paramType = call.getTarget().getParameter(argIndex).getType() + or + paramType = getExprCallFunctionType(call).getParameterType(argIndex) + ) + } + + /** + * Get the `FunctionExpr` or `FunctionCall` that this argument appears in. + */ + Call getCall() { result = call } + + /** + * Gets the `Type` of the parameter corresponding to this argument, whether its based on the target function or the function pointer type. + */ + Type getParamType() { result = paramType } + + /** + * Get the argument index of this argument in the call. + */ + int getArgIndex() { result = argIndex } + + /** + * Get the target `Function` if this is an argument to a `FunctionCall`. + */ + Function getKnownFunction() { result = call.getTarget() } + + /** + * Get the target `Parameter` if this is an argument to a `FunctionCall`. + */ + Parameter getKnownParameter() { result = call.getTarget().getParameter(argIndex) } +} From a726f72aa75040eab37df27b445dd03a4ac1e16b Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 3 Apr 2026 16:40:52 -0700 Subject: [PATCH 05/10] Update query metadata --- cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql | 3 ++- rule_packages/cpp/Declarations6.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql index 9b0d1f5c43..988262f4fb 100644 --- a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql +++ b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql @@ -8,8 +8,9 @@ * @precision high * @problem.severity warning * @tags external/misra/id/rule-10-1-1 - * maintainability + * correctness * readability + * performance * scope/single-translation-unit * external/misra/enforcement/decidable * external/misra/obligation/advisory diff --git a/rule_packages/cpp/Declarations6.json b/rule_packages/cpp/Declarations6.json index 7736f0b1ab..05d39eb339 100644 --- a/rule_packages/cpp/Declarations6.json +++ b/rule_packages/cpp/Declarations6.json @@ -14,8 +14,9 @@ "severity": "warning", "short_name": "PointerOrRefParamNotConst", "tags": [ - "maintainability", + "correctness", "readability", + "performance", "scope/single-translation-unit" ] } From 1edab32de7419de0b4d9d1852162b5a3c18b9a7d Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 3 Apr 2026 16:41:54 -0700 Subject: [PATCH 06/10] Commit changes to rules.csv --- rules.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules.csv b/rules.csv index 683326a6c3..a8aa9bf0bf 100644 --- a/rules.csv +++ b/rules.csv @@ -915,7 +915,7 @@ cpp,MISRA-C++-2023,RULE-9-6-3,Yes,Required,Decidable,Single Translation Unit,The cpp,MISRA-C++-2023,RULE-9-6-4,Yes,Required,Undecidable,System,A function declared with the [[noreturn]] attribute shall not return,MSC53-CPP,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-9-6-5,Yes,Required,Decidable,Single Translation Unit,A function with non-void return type shall return a value on all paths,MSC52-CPP,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-10-0-1,Yes,Advisory,Decidable,Single Translation Unit,A declaration should not declare more than one variable or member variable,M8-0-1,ImportMisra23,Import, -cpp,MISRA-C++-2023,RULE-10-1-1,Yes,Advisory,Decidable,Single Translation Unit,The target type of a pointer or lvalue reference parameter should be const-qualified appropriately,RULE-8-13,Declarations3,Hard, +cpp,MISRA-C++-2023,RULE-10-1-1,Yes,Advisory,Decidable,Single Translation Unit,The target type of a pointer or lvalue reference parameter should be const-qualified appropriately,RULE-8-13,Declarations6,Hard, cpp,MISRA-C++-2023,RULE-10-1-2,Yes,Required,Decidable,Single Translation Unit,The volatile qualifier shall be used appropriately,,Declarations2,Easy, cpp,MISRA-C++-2023,RULE-10-2-1,Yes,Required,Decidable,Single Translation Unit,An enumeration shall be defined with an explicit underlying type,A7-2-2,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-10-2-2,Yes,Advisory,Decidable,Single Translation Unit,Unscoped enumerations should not be declared,A7-2-3,Banned,Easy, From 96977d07883296f483588b33c6c120a4aec06f4b Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 3 Apr 2026 16:44:53 -0700 Subject: [PATCH 07/10] Update exclusion check to Declarations6 --- cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql index 988262f4fb..eab0c7895d 100644 --- a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql +++ b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql @@ -258,7 +258,7 @@ class NonConstParam extends PointerLikeParam { from NonConstParam param, Type innerType where - not isExcluded(param, Declarations3Package::pointerOrRefParamNotConstQuery()) and + not isExcluded(param, Declarations6Package::pointerOrRefParamNotConstQuery()) and innerType = param.getPointerLikeType().getInnerType() and not param.isAffectedByMacro() and // Exclude functions with copied parameters which leads to wrong results. From c06ea922b110bbaaf4f2228ae96e9e2e7e23318e Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 3 Apr 2026 16:48:53 -0700 Subject: [PATCH 08/10] Delete test predicate, clarify multiple param exclusion --- .../RULE-10-1-1/PointerOrRefParamNotConst.ql | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql index eab0c7895d..0c3eeacc98 100644 --- a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql +++ b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql @@ -135,24 +135,6 @@ class PointerLikeParam extends Parameter { } } -predicate test(Assignment a, Field f, Parameter p, string n) { - a.getLValue() = f.getAnAccess() and - a.getRValue() = p.getAnAccess() and - f.getName() = "planes" and - n = p.getFunction().getName() and - a.getFile().getBaseName() = "matrix_iterator.cpp" -} - -predicate test2(Parameter p) { - p.getName() = ["planes", "_planes"] and - p.getFunction().getName() = "init" -} - -predicate test3(Function f, int num) { - f.getName() = "init" and - num = strictcount(Parameter p | p.getFunction() = f and p.getName() = ["planes", "_planes"]) -} - /** * A `VariableEffect` whose target variable is a `PointerLikeParam`. * @@ -261,7 +243,9 @@ where not isExcluded(param, Declarations6Package::pointerOrRefParamNotConstQuery()) and innerType = param.getPointerLikeType().getInnerType() and not param.isAffectedByMacro() and - // Exclude functions with copied parameters which leads to wrong results. + // There are some odd database patterns where a function has multiple parameters with the same + // index and different names, due to strange extraction+linker scenarios. These give wrong + // results, and should be excluded. count(Parameter p | p.getFunction() = param.getFunction() and p.getIndex() = param.getIndex() From 71e67e0672357cc9973a2f603961dc5d3cfc17c3 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 3 Apr 2026 16:53:24 -0700 Subject: [PATCH 09/10] Copilot feedback --- cpp/common/src/codingstandards/cpp/Call.qll | 11 ++++++----- .../rules/RULE-10-1-1/PointerOrRefParamNotConst.ql | 14 ++++++-------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/Call.qll b/cpp/common/src/codingstandards/cpp/Call.qll index dd2bf013f6..22fde8c295 100644 --- a/cpp/common/src/codingstandards/cpp/Call.qll +++ b/cpp/common/src/codingstandards/cpp/Call.qll @@ -37,27 +37,28 @@ class CallArgumentExpr extends Expr { } /** - * Get the `FunctionExpr` or `FunctionCall` that this argument appears in. + * Gets the `FunctionExpr` or `FunctionCall` that this argument appears in. */ Call getCall() { result = call } /** - * Gets the `Type` of the parameter corresponding to this argument, whether its based on the target function or the function pointer type. + * Gets the `Type` of the parameter corresponding to this argument, whether its based on the + * target function or the function pointer type. */ Type getParamType() { result = paramType } /** - * Get the argument index of this argument in the call. + * Gets the argument index of this argument in the call. */ int getArgIndex() { result = argIndex } /** - * Get the target `Function` if this is an argument to a `FunctionCall`. + * Gets the target `Function` if this is an argument to a `FunctionCall`. */ Function getKnownFunction() { result = call.getTarget() } /** - * Get the target `Parameter` if this is an argument to a `FunctionCall`. + * Gets the target `Parameter` if this is an argument to a `FunctionCall`. */ Parameter getKnownParameter() { result = call.getTarget().getParameter(argIndex) } } diff --git a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql index 0c3eeacc98..8db0014920 100644 --- a/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql +++ b/cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql @@ -21,7 +21,6 @@ import codingstandards.cpp.misra import codingstandards.cpp.types.Pointers import codingstandards.cpp.Call import codingstandards.cpp.SideEffect -import codingstandards.cpp.alertreporting.HoldsForAllCopies /** * Holds if the function is in a template scope and should be excluded. @@ -35,7 +34,7 @@ predicate isInTemplateScope(Function f) { /** * A `Type` that may be a pointer, array, or reference, to a const or a non-const type. * - * For example, `const int*`, `int* const`, `cont int* const`, `int*`, `int&`, `const int&` are all + * For example, `const int*`, `int* const`, `const int* const`, `int*`, `int&`, `const int&` are all * `PointerLikeType`s, while `int`, `int&&`, and `const int` are not. * * To check if a `PointerLikeType` points/refers to a const-qualified type, use the `pointsToConst()` @@ -61,12 +60,12 @@ class PointerLikeType extends Type { } /** - * Get the pointed to or referred to type, for instance `int` for `int*` or `const int&`. + * Gets the pointed to or referred to type, for instance `int` for `int*` or `const int&`. */ Type getInnerType() { result = innerType } /** - * Get the resolved pointer, array, or reference type itself, for instance `int*` in `int* const`. + * Gets the resolved pointer, array, or reference type itself, for instance `int*` in `int* const`. * * Removes cv-qualification and resolves typedefs and decltypes and specifiers via * `stripTopLevelSpecifiers()`. @@ -80,7 +79,7 @@ class PointerLikeType extends Type { predicate pointsToConst() { innerType.isConst() } /** - * Holds when this type points to non-const -- for example, `int*` and `int&` and `int const*` + * Holds when this type points to non-const -- for example, `int*` and `int&` and `int *const` * point to non-const, while `const int*`, `const int&` do not. */ predicate pointsToNonConst() { not innerType.isConst() } @@ -100,12 +99,12 @@ class PointerLikeParam extends Parameter { } /** - * Get the pointer like type of this parameter. + * Gets the pointer like type of this parameter. */ PointerLikeType getPointerLikeType() { result = pointerLikeType } /** - * Get usages of this parameter that maintain pointer-like semantics -- typically this means + * Gets usages of this parameter that maintain pointer-like semantics -- typically this means * either a normal access, or switching between pointers and reference semantics. * * Examples of accesses with pointer-like semantics include: @@ -177,7 +176,6 @@ class PointerLikeEffect extends VariableEffect { class NonConstParam extends PointerLikeParam { NonConstParam() { not pointerLikeType.pointsToConst() and - not pointerLikeType.getInnerType() instanceof VoidType and // Ignore parameters in functions without bodies exists(this.getFunction().getBlock()) and // Ignore unnamed parameters From 7fa8d1b95a1b2a2532d7deb95f80394469b3c938 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 3 Apr 2026 17:10:59 -0700 Subject: [PATCH 10/10] Delete duplicated test block --- .../PointerOrRefParamNotConst.expected | 42 +++++++++---------- cpp/misra/test/rules/RULE-10-1-1/test.cpp | 11 ----- 2 files changed, 19 insertions(+), 34 deletions(-) diff --git a/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected b/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected index 85b24a4ab6..bd3262e6c6 100644 --- a/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected +++ b/cpp/misra/test/rules/RULE-10-1-1/PointerOrRefParamNotConst.expected @@ -27,26 +27,22 @@ | test.cpp:91:20:91:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:91:5:91:5 | definition of operator() | function definition | | test.cpp:93:20:93:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:93:5:93:5 | definition of operator() | function definition | | test.cpp:95:20:95:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:95:5:95:5 | definition of operator() | function definition | -| test.cpp:100:20:100:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:100:5:100:5 | definition of operator() | function definition | -| test.cpp:102:20:102:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:102:5:102:5 | definition of operator() | function definition | -| test.cpp:104:20:104:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:104:5:104:5 | definition of operator() | function definition | -| test.cpp:106:20:106:21 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:106:5:106:5 | definition of operator() | function definition | -| test.cpp:142:26:142:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:142:5:142:5 | definition of operator() | function definition | -| test.cpp:143:26:143:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:143:5:143:5 | definition of operator() | function definition | -| test.cpp:144:26:144:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:144:5:144:5 | definition of operator() | function definition | -| test.cpp:145:26:145:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:145:5:145:5 | definition of operator() | function definition | -| test.cpp:146:26:146:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:146:5:146:5 | definition of operator() | function definition | -| test.cpp:147:26:147:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:147:5:147:5 | definition of operator() | function definition | -| test.cpp:148:12:148:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:148:5:148:5 | definition of operator() | function definition | -| test.cpp:149:12:149:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:149:5:149:5 | definition of operator() | function definition | -| test.cpp:150:12:150:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:150:5:150:5 | definition of operator() | function definition | -| test.cpp:151:12:151:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:151:5:151:5 | definition of operator() | function definition | -| test.cpp:152:12:152:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:152:5:152:5 | definition of operator() | function definition | -| test.cpp:153:12:153:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:153:5:153:5 | definition of operator() | function definition | -| test.cpp:156:23:156:24 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:156:6:156:7 | definition of f5 | function definition | -| test.cpp:159:23:159:24 | p4 | Parameter 'p4' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:156:6:156:7 | definition of f5 | function definition | -| test.cpp:164:23:164:24 | p9 | Parameter 'p9' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:156:6:156:7 | definition of f5 | function definition | -| test.cpp:165:23:165:25 | p10 | Parameter 'p10' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:156:6:156:7 | definition of f5 | function definition | -| test.cpp:167:23:167:25 | p12 | Parameter 'p12' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:156:6:156:7 | definition of f5 | function definition | -| test.cpp:198:12:198:13 | p2 | Parameter 'p2' points/refers to a non-const type 'S' but does not modify the target object in the $@. | test.cpp:197:6:197:7 | definition of f6 | function definition | -| test.cpp:209:23:209:24 | p4 | Parameter 'p4' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:206:6:206:7 | definition of f7 | function definition | +| test.cpp:131:26:131:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:131:5:131:5 | definition of operator() | function definition | +| test.cpp:132:26:132:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:132:5:132:5 | definition of operator() | function definition | +| test.cpp:133:26:133:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:133:5:133:5 | definition of operator() | function definition | +| test.cpp:134:26:134:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:134:5:134:5 | definition of operator() | function definition | +| test.cpp:135:26:135:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:135:5:135:5 | definition of operator() | function definition | +| test.cpp:136:26:136:27 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:136:5:136:5 | definition of operator() | function definition | +| test.cpp:137:12:137:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:137:5:137:5 | definition of operator() | function definition | +| test.cpp:138:12:138:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:138:5:138:5 | definition of operator() | function definition | +| test.cpp:139:12:139:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:139:5:139:5 | definition of operator() | function definition | +| test.cpp:140:12:140:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:140:5:140:5 | definition of operator() | function definition | +| test.cpp:141:12:141:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:141:5:141:5 | definition of operator() | function definition | +| test.cpp:142:12:142:13 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:142:5:142:5 | definition of operator() | function definition | +| test.cpp:145:23:145:24 | p1 | Parameter 'p1' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:145:6:145:7 | definition of f5 | function definition | +| test.cpp:148:23:148:24 | p4 | Parameter 'p4' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:145:6:145:7 | definition of f5 | function definition | +| test.cpp:153:23:153:24 | p9 | Parameter 'p9' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:145:6:145:7 | definition of f5 | function definition | +| test.cpp:154:23:154:25 | p10 | Parameter 'p10' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:145:6:145:7 | definition of f5 | function definition | +| test.cpp:156:23:156:25 | p12 | Parameter 'p12' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:145:6:145:7 | definition of f5 | function definition | +| test.cpp:187:12:187:13 | p2 | Parameter 'p2' points/refers to a non-const type 'S' but does not modify the target object in the $@. | test.cpp:186:6:186:7 | definition of f6 | function definition | +| test.cpp:198:23:198:24 | p4 | Parameter 'p4' points/refers to a non-const type 'int32_t' but does not modify the target object in the $@. | test.cpp:195:6:195:7 | definition of f7 | function definition | diff --git a/cpp/misra/test/rules/RULE-10-1-1/test.cpp b/cpp/misra/test/rules/RULE-10-1-1/test.cpp index 912ec297e2..abdd879109 100644 --- a/cpp/misra/test/rules/RULE-10-1-1/test.cpp +++ b/cpp/misra/test/rules/RULE-10-1-1/test.cpp @@ -96,17 +96,6 @@ void f4() { return &p1; }; // NON_COMPLIANT - // Returning from reference parameters - [](std::int32_t &p1) -> std::int32_t { return p1; }; // NON_COMPLIANT - [](std::int32_t &p1) -> std::int32_t & { return p1; }; // COMPLIANT - [](std::int32_t &p1) -> const std::int32_t & { return p1; }; // NON_COMPLIANT - [](std::int32_t &p1) -> std::int32_t * { return &p1; }; // COMPLIANT - [](std::int32_t &p1) -> const std::int32_t * { return &p1; }; // NON_COMPLIANT - [](std::int32_t &p1) -> std::int32_t *const { return &p1; }; // COMPLIANT - [](std::int32_t &p1) -> const std::int32_t *const { - return &p1; - }; // NON_COMPLIANT - // Non compliant cases are compliant when const using cpi32 = const std::int32_t *; using cri32 = const std::int32_t &;