Skip to content

Commit ef6492b

Browse files
initial commit
1 parent ad580d3 commit ef6492b

File tree

9 files changed

+577
-3
lines changed

9 files changed

+577
-3
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
2+
import cpp
3+
import RuleMetadata
4+
import codingstandards.cpp.exclusions.RuleMetadata
5+
6+
newtype Declarations3Query = TPointerOrRefParamNotConstQuery()
7+
8+
predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleId, string category) {
9+
query =
10+
// `Query` instance for the `pointerOrRefParamNotConst` query
11+
Declarations3Package::pointerOrRefParamNotConstQuery() and
12+
queryId =
13+
// `@id` for the `pointerOrRefParamNotConst` query
14+
"cpp/misra/pointer-or-ref-param-not-const" and
15+
ruleId = "RULE-10-1-1" and
16+
category = "advisory"
17+
}
18+
19+
module Declarations3Package {
20+
Query pointerOrRefParamNotConstQuery() {
21+
//autogenerate `Query` type
22+
result =
23+
// `Query` type for `pointerOrRefParamNotConst` query
24+
TQueryCPP(TDeclarations3PackageQuery(TPointerOrRefParamNotConstQuery()))
25+
}
26+
}

cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import DeadCode8
2828
import DeadCode9
2929
import Declarations
3030
import Declarations1
31+
import Declarations3
3132
import ExceptionSafety
3233
import Exceptions1
3334
import Exceptions2
@@ -119,6 +120,7 @@ newtype TCPPQuery =
119120
TDeadCode9PackageQuery(DeadCode9Query q) or
120121
TDeclarationsPackageQuery(DeclarationsQuery q) or
121122
TDeclarations1PackageQuery(Declarations1Query q) or
123+
TDeclarations3PackageQuery(Declarations3Query q) or
122124
TExceptionSafetyPackageQuery(ExceptionSafetyQuery q) or
123125
TExceptions1PackageQuery(Exceptions1Query q) or
124126
TExceptions2PackageQuery(Exceptions2Query q) or
@@ -210,6 +212,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
210212
isDeadCode9QueryMetadata(query, queryId, ruleId, category) or
211213
isDeclarationsQueryMetadata(query, queryId, ruleId, category) or
212214
isDeclarations1QueryMetadata(query, queryId, ruleId, category) or
215+
isDeclarations3QueryMetadata(query, queryId, ruleId, category) or
213216
isExceptionSafetyQueryMetadata(query, queryId, ruleId, category) or
214217
isExceptions1QueryMetadata(query, queryId, ruleId, category) or
215218
isExceptions2QueryMetadata(query, queryId, ruleId, category) or

cpp/common/test/includes/standard-library/vector.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ template <class T, class Allocator = std::allocator<T>> class vector {
2020

2121
iterator begin();
2222
iterator end();
23-
const_iterator cbegin();
24-
const_iterator cend();
23+
const_iterator cbegin() const;
24+
const_iterator cend() const;
2525
size_type size() const noexcept;
2626
void resize(size_type sz);
2727
void resize(size_type sz, const T &c);
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/**
2+
* @id cpp/misra/pointer-or-ref-param-not-const
3+
* @name RULE-10-1-1: The target type of a pointer or lvalue reference parameter should be const-qualified appropriately
4+
* @description Pointer or lvalue reference parameters that do not modify the target object should
5+
* be const-qualified to accurately reflect function behavior and prevent unintended
6+
* modifications.
7+
* @kind problem
8+
* @precision high
9+
* @problem.severity warning
10+
* @tags external/misra/id/rule-10-1-1
11+
* maintainability
12+
* readability
13+
* scope/single-translation-unit
14+
* external/misra/enforcement/decidable
15+
* external/misra/obligation/advisory
16+
*/
17+
18+
import cpp
19+
import codingstandards.cpp.misra
20+
import codingstandards.cpp.types.Pointers
21+
import codingstandards.cpp.SideEffect
22+
import codingstandards.cpp.alertreporting.HoldsForAllCopies
23+
24+
/**
25+
* Holds if the function is in a template scope and should be excluded.
26+
*/
27+
predicate isInTemplateScope(Function f) {
28+
// Function templates
29+
f.isFromTemplateInstantiation(_)
30+
or
31+
f instanceof TemplateFunction
32+
or
33+
// Functions declared within the scope of a template class
34+
exists(TemplateClass tc | f.getDeclaringType() = tc)
35+
or
36+
f.getDeclaringType().isFromTemplateInstantiation(_)
37+
or
38+
// Lambdas within template scope
39+
exists(LambdaExpression le |
40+
le.getLambdaFunction() = f and
41+
isInTemplateScope(le.getEnclosingFunction())
42+
)
43+
}
44+
45+
/**
46+
* A `Type` that may be a pointer, array, or reference, to a const or a non-const type.
47+
*
48+
* For example, `const int*`, `int* const`, `cont int* const`, `int*`, `int&`, `const int&` are all
49+
* `PointerLikeType`s, while `int`, `int&&`, and `const int` are not.
50+
*
51+
* To check if a `PointerLikeType` points/refers to a const-qualified type, use the `pointsToConst()`
52+
* predicate.
53+
*/
54+
class PointerLikeType extends Type {
55+
Type innerType;
56+
Type outerType;
57+
58+
PointerLikeType() {
59+
innerType = this.(UnspecifiedPointerOrArrayType).getBaseType() and
60+
outerType = this
61+
or
62+
innerType = this.(LValueReferenceType).getBaseType() and
63+
outerType = this
64+
or
65+
exists(PointerLikeType stripped |
66+
stripped = this.stripTopLevelSpecifiers() and not stripped = this
67+
|
68+
innerType = stripped.getInnerType() and
69+
outerType = stripped.getOuterType()
70+
)
71+
}
72+
73+
/**
74+
* Get the pointed to or referred to type, for instance `int` for `int*` or `const int&`.
75+
*/
76+
Type getInnerType() { result = innerType }
77+
78+
/**
79+
* Get the resolved pointer, array, or reference type itself, for instance `int*` in `int* const`.
80+
*
81+
* Removes cv-qualification and resolves typedefs and decltypes and specifiers via
82+
* `stripTopLevelSpecifiers()`.
83+
*/
84+
Type getOuterType() { result = outerType }
85+
86+
/**
87+
* Holds when this type points to const -- for example, `const int*` and `const int&` point to
88+
* const, while `int*`, `int *const` and `int&` do not.
89+
*/
90+
predicate pointsToConst() { innerType.isConst() }
91+
92+
/**
93+
* Holds when this type points to non-const -- for example, `int*` and `int&` and `int const*`
94+
* point to non-const, while `const int*`, `const int&` do not.
95+
*/
96+
predicate pointsToNonConst() { not innerType.isConst() }
97+
}
98+
99+
class PointerLikeParam extends Parameter {
100+
PointerLikeType pointerLikeType;
101+
102+
PointerLikeParam() {
103+
pointerLikeType = this.getType() and
104+
not pointerLikeType.pointsToConst() and
105+
// Exclude pointers to non-object types
106+
not pointerLikeType.getInnerType() instanceof RoutineType and
107+
not pointerLikeType.getInnerType() instanceof VoidType
108+
}
109+
110+
Expr getAPointerLikeAccess() {
111+
result = this.getAnAccess()
112+
or
113+
// For reference parameters, also consider accesses to the parameter itself as accesses to the referent
114+
pointerLikeType.getOuterType() instanceof ReferenceType and
115+
result.(AddressOfExpr).getOperand() = this.getAnAccess()
116+
or
117+
// A pointer is dereferenced, but the result is not copied
118+
pointerLikeType.getOuterType() instanceof PointerType and
119+
result.(PointerDereferenceExpr).getOperand() = this.getAnAccess() and
120+
not any(ReferenceDereferenceExpr rde).getExpr() = result.getConversion+()
121+
}
122+
}
123+
124+
query predicate test(
125+
PointerLikeParam param, Expr ptrLikeAccess, Type argtype, Type innerType, string explain
126+
) {
127+
ptrLikeAccess = param.getAPointerLikeAccess() and
128+
exists(FunctionCall fc |
129+
fc.getArgument(0) = ptrLikeAccess and
130+
argtype = fc.getTarget().getParameter(0).getType() and
131+
argtype.(PointerLikeType).pointsToNonConst() and
132+
innerType = argtype.(PointerLikeType).getInnerType()
133+
) and
134+
explain = argtype.explain()
135+
}
136+
137+
/**
138+
* A candidate parameter that could have its target type const-qualified.
139+
*/
140+
class NonConstParam extends PointerLikeParam {
141+
NonConstParam() {
142+
not pointerLikeType.pointsToConst() and
143+
// Ignore parameters in functions without bodies
144+
exists(this.getFunction().getBlock()) and
145+
// Ignore unnamed parameters
146+
this.isNamed() and
147+
// Ignore functions that use ASM statements
148+
not exists(AsmStmt a | a.getEnclosingFunction() = this.getFunction()) and
149+
// Must have a pointer, array, or lvalue reference type with non-const target
150+
// Exclude pointers to non-object types
151+
not pointerLikeType.getInnerType() instanceof RoutineType and
152+
not pointerLikeType.getInnerType() instanceof VoidType and
153+
// Exclude virtual functions
154+
not this.getFunction().isVirtual() and
155+
// Exclude functions in template scope
156+
not isInTemplateScope(this.getFunction()) and
157+
// Exclude main
158+
not this.getFunction().hasGlobalName("main") and
159+
// Exclude deleted functions
160+
not this.getFunction().isDeleted() and
161+
// Exclude any parameter whose underlying data is modified (VariableEffect)
162+
not exists(VariableEffect effect |
163+
effect.getTarget() = this and
164+
(
165+
// For reference types, any effect is a target modification
166+
pointerLikeType.getOuterType() instanceof ReferenceType
167+
or
168+
// For pointer types, exclude effects that only modify the pointer itself
169+
not effect.(AssignExpr).getLValue() = this.getAnAccess() and
170+
not effect.(CrementOperation).getOperand() = this.getAnAccess()
171+
)
172+
) and
173+
// Exclude parameters passed as arguments to functions taking non-const pointer/ref params
174+
not exists(FunctionCall fc, int i |
175+
fc.getArgument(i) = this.getAPointerLikeAccess() and
176+
fc.getTarget().getParameter(i).getType().(PointerLikeType).pointsToNonConst()
177+
) and
178+
// Exclude parameters used as qualifier for a non-const member function
179+
not exists(FunctionCall fc |
180+
fc.getQualifier() = this.getAnAccess() and
181+
not fc.getTarget().hasSpecifier("const") and
182+
not fc.getTarget().isStatic()
183+
) and
184+
// Exclude parameters assigned to a non-const pointer/reference alias
185+
not exists(Variable v |
186+
v.getAnAssignedValue() = this.getAnAccess() and
187+
v.getType().(PointerLikeType).pointsToNonConst()
188+
) and
189+
// Exclude parameters returned as non-const pointer/reference
190+
not exists(ReturnStmt ret |
191+
ret.getExpr() = this.getAnAccess() and
192+
ret.getEnclosingFunction().getType().(PointerLikeType).pointsToNonConst()
193+
)
194+
}
195+
}
196+
197+
from NonConstParam param
198+
where not isExcluded(param, Declarations3Package::pointerOrRefParamNotConstQuery())
199+
select param,
200+
"Parameter '" + param.getName() +
201+
"' points/refers to a non-const-qualified type but does not modify the target object."
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
test
2+
| 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"} |
3+
| 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"} |
4+
| 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"} |
5+
| 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"}} |
6+
| 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"} |
7+
| 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"}} |
8+
#select
9+
| test.cpp:4:22:4:23 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
10+
| test.cpp:7:28:7:29 | p4 | Parameter 'p4' points/refers to a non-const-qualified type but does not modify the target object. |
11+
| test.cpp:8:21:8:22 | p5 | Parameter 'p5' points/refers to a non-const-qualified type but does not modify the target object. |
12+
| test.cpp:19:36:19:37 | l2 | Parameter 'l2' points/refers to a non-const-qualified type but does not modify the target object. |
13+
| test.cpp:40:20:40:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
14+
| test.cpp:41:20:41:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
15+
| test.cpp:42:20:42:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
16+
| test.cpp:43:20:43:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
17+
| test.cpp:45:20:45:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
18+
| test.cpp:46:20:46:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
19+
| test.cpp:50:20:50:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
20+
| test.cpp:51:20:51:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
21+
| test.cpp:54:20:54:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
22+
| test.cpp:55:20:55:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
23+
| test.cpp:60:20:60:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
24+
| test.cpp:61:20:61:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
25+
| test.cpp:62:20:62:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
26+
| test.cpp:63:20:63:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
27+
| test.cpp:68:20:68:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
28+
| test.cpp:70:20:70:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
29+
| test.cpp:71:20:71:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
30+
| test.cpp:72:20:72:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
31+
| test.cpp:73:20:73:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
32+
| test.cpp:74:20:74:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
33+
| test.cpp:78:20:78:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
34+
| test.cpp:79:20:79:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
35+
| test.cpp:80:20:80:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
36+
| test.cpp:82:20:82:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
37+
| test.cpp:84:20:84:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
38+
| test.cpp:89:20:89:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
39+
| test.cpp:91:20:91:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
40+
| test.cpp:92:20:92:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
41+
| test.cpp:93:20:93:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
42+
| test.cpp:94:20:94:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
43+
| test.cpp:95:20:95:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
44+
| test.cpp:100:20:100:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
45+
| test.cpp:102:20:102:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
46+
| test.cpp:103:20:103:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
47+
| test.cpp:104:20:104:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
48+
| test.cpp:105:20:105:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
49+
| test.cpp:106:20:106:21 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
50+
| test.cpp:142:26:142:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
51+
| test.cpp:143:26:143:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
52+
| test.cpp:144:26:144:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
53+
| test.cpp:145:26:145:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
54+
| test.cpp:146:26:146:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
55+
| test.cpp:147:26:147:27 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
56+
| test.cpp:148:12:148:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
57+
| test.cpp:149:12:149:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
58+
| test.cpp:150:12:150:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
59+
| test.cpp:151:12:151:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
60+
| test.cpp:152:12:152:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
61+
| test.cpp:153:12:153:13 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
62+
| test.cpp:156:23:156:24 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
63+
| test.cpp:164:23:164:24 | p9 | Parameter 'p9' points/refers to a non-const-qualified type but does not modify the target object. |
64+
| test.cpp:165:23:165:25 | p10 | Parameter 'p10' points/refers to a non-const-qualified type but does not modify the target object. |
65+
| test.cpp:167:23:167:25 | p12 | Parameter 'p12' points/refers to a non-const-qualified type but does not modify the target object. |
66+
| test.cpp:198:12:198:13 | p2 | Parameter 'p2' points/refers to a non-const-qualified type but does not modify the target object. |
67+
| test.cpp:199:12:199:13 | p3 | Parameter 'p3' points/refers to a non-const-qualified type but does not modify the target object. |
68+
| test.cpp:206:23:206:24 | p1 | Parameter 'p1' points/refers to a non-const-qualified type but does not modify the target object. |
69+
| test.cpp:208:23:208:24 | p3 | Parameter 'p3' points/refers to a non-const-qualified type but does not modify the target object. |
70+
| test.cpp:209:23:209:24 | p4 | Parameter 'p4' points/refers to a non-const-qualified type but does not modify the target object. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-10-1-1/PointerOrRefParamNotConst.ql

0 commit comments

Comments
 (0)