Skip to content

Commit f843ac1

Browse files
Move pointer functionality into common/types/pointers
1 parent 7fa8d1b commit f843ac1

File tree

2 files changed

+87
-66
lines changed

2 files changed

+87
-66
lines changed

cpp/common/src/codingstandards/cpp/types/Pointers.qll

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,89 @@ Type baseType(Type t) {
125125
// Make sure that the type has a size and that it isn't ambiguous.
126126
strictcount(result.getSize()) = 1
127127
}
128+
129+
/**
130+
* A `Type` that may be a pointer, array, or reference, to a const or a non-const type.
131+
*
132+
* For example, `const int*`, `int* const`, `const int* const`, `int*`, `int&`, `const int&` are all
133+
* `PointerLikeType`s, while `int`, `int&&`, and `const int` are not.
134+
*
135+
* To check if a `PointerLikeType` points/refers to a const-qualified type, use the `pointsToConst()`
136+
* predicate.
137+
*/
138+
class PointerLikeType extends Type {
139+
Type innerType;
140+
Type outerType;
141+
142+
PointerLikeType() {
143+
innerType = this.(UnspecifiedPointerOrArrayType).getBaseType() and
144+
outerType = this
145+
or
146+
innerType = this.(LValueReferenceType).getBaseType() and
147+
outerType = this
148+
or
149+
exists(PointerLikeType stripped |
150+
stripped = this.stripTopLevelSpecifiers() and not stripped = this
151+
|
152+
innerType = stripped.getInnerType() and
153+
outerType = stripped.getOuterType()
154+
)
155+
}
156+
157+
/**
158+
* Gets the pointed to or referred to type, for instance `int` for `int*` or `const int&`.
159+
*/
160+
Type getInnerType() { result = innerType }
161+
162+
/**
163+
* Gets the resolved pointer, array, or reference type itself, for instance `int*` in `int* const`.
164+
*
165+
* Removes cv-qualification and resolves typedefs and decltypes and specifiers via
166+
* `stripTopLevelSpecifiers()`.
167+
*/
168+
Type getOuterType() { result = outerType }
169+
170+
/**
171+
* Holds when this type points to const -- for example, `const int*` and `const int&` point to
172+
* const, while `int*`, `int *const` and `int&` do not.
173+
*/
174+
predicate pointsToConst() { innerType.isConst() }
175+
176+
/**
177+
* Holds when this type points to non-const -- for example, `int*` and `int&` and `int *const`
178+
* point to non-const, while `const int*`, `const int&` do not.
179+
*/
180+
predicate pointsToNonConst() { not innerType.isConst() }
181+
}
182+
183+
/**
184+
* Gets usages of this parameter that maintain pointer-like semantics -- typically this means
185+
* either a normal access, or switching between pointers and reference semantics.
186+
*
187+
* Examples of accesses with pointer-like semantics include:
188+
* - `ref` in `int &x = ref`, or `&ref` in `int *x = &ref`;
189+
* - `ptr` in `int *x = ptr`, or `*ptr` in `int &x = *ptr`;
190+
*
191+
* In the above examples, we can still access the value pointed to by `ref` or `ptr` through the
192+
* expression.
193+
*
194+
* Examples of non-pointer-like semantics include:
195+
* - `ref` in `int x = ref` and `*ptr` in `int x = *ptr`;
196+
*
197+
* In the above examples, the value pointed to by `ref` or `ptr` is copied and the expression
198+
* refers to a new/different object.
199+
*/
200+
Expr getAPointerLikeAccessOf(Expr expr) {
201+
exists(PointerLikeType pointerLikeType | pointerLikeType = expr.getType() |
202+
result = expr
203+
or
204+
// For reference parameters, also consider accesses to the parameter itself as accesses to the referent
205+
pointerLikeType.getOuterType() instanceof ReferenceType and
206+
result.(AddressOfExpr).getOperand() = expr
207+
or
208+
// A pointer is dereferenced, but the result is not copied
209+
pointerLikeType.getOuterType() instanceof PointerType and
210+
result.(PointerDereferenceExpr).getOperand() = expr and
211+
not any(ReferenceDereferenceExpr rde).getExpr() = result.getConversion+()
212+
)
213+
}

cpp/misra/src/rules/RULE-10-1-1/PointerOrRefParamNotConst.ql

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -31,60 +31,6 @@ predicate isInTemplateScope(Function f) {
3131
f.isFromUninstantiatedTemplate(_)
3232
}
3333

34-
/**
35-
* A `Type` that may be a pointer, array, or reference, to a const or a non-const type.
36-
*
37-
* For example, `const int*`, `int* const`, `const int* const`, `int*`, `int&`, `const int&` are all
38-
* `PointerLikeType`s, while `int`, `int&&`, and `const int` are not.
39-
*
40-
* To check if a `PointerLikeType` points/refers to a const-qualified type, use the `pointsToConst()`
41-
* predicate.
42-
*/
43-
class PointerLikeType extends Type {
44-
Type innerType;
45-
Type outerType;
46-
47-
PointerLikeType() {
48-
innerType = this.(UnspecifiedPointerOrArrayType).getBaseType() and
49-
outerType = this
50-
or
51-
innerType = this.(LValueReferenceType).getBaseType() and
52-
outerType = this
53-
or
54-
exists(PointerLikeType stripped |
55-
stripped = this.stripTopLevelSpecifiers() and not stripped = this
56-
|
57-
innerType = stripped.getInnerType() and
58-
outerType = stripped.getOuterType()
59-
)
60-
}
61-
62-
/**
63-
* Gets the pointed to or referred to type, for instance `int` for `int*` or `const int&`.
64-
*/
65-
Type getInnerType() { result = innerType }
66-
67-
/**
68-
* Gets the resolved pointer, array, or reference type itself, for instance `int*` in `int* const`.
69-
*
70-
* Removes cv-qualification and resolves typedefs and decltypes and specifiers via
71-
* `stripTopLevelSpecifiers()`.
72-
*/
73-
Type getOuterType() { result = outerType }
74-
75-
/**
76-
* Holds when this type points to const -- for example, `const int*` and `const int&` point to
77-
* const, while `int*`, `int *const` and `int&` do not.
78-
*/
79-
predicate pointsToConst() { innerType.isConst() }
80-
81-
/**
82-
* Holds when this type points to non-const -- for example, `int*` and `int&` and `int *const`
83-
* point to non-const, while `const int*`, `const int&` do not.
84-
*/
85-
predicate pointsToNonConst() { not innerType.isConst() }
86-
}
87-
8834
/**
8935
* A `Parameter` whose type is a `PointerLikeType` such as a pointer or reference.
9036
*/
@@ -120,18 +66,7 @@ class PointerLikeParam extends Parameter {
12066
* In the above examples, the value pointed to by `ref` or `ptr` is copied and the expression
12167
* refers to a new/different object.
12268
*/
123-
Expr getAPointerLikeAccess() {
124-
result = this.getAnAccess()
125-
or
126-
// For reference parameters, also consider accesses to the parameter itself as accesses to the referent
127-
pointerLikeType.getOuterType() instanceof ReferenceType and
128-
result.(AddressOfExpr).getOperand() = this.getAnAccess()
129-
or
130-
// A pointer is dereferenced, but the result is not copied
131-
pointerLikeType.getOuterType() instanceof PointerType and
132-
result.(PointerDereferenceExpr).getOperand() = this.getAnAccess() and
133-
not any(ReferenceDereferenceExpr rde).getExpr() = result.getConversion+()
134-
}
69+
Expr getAPointerLikeAccess() { result = getAPointerLikeAccessOf(this.getAnAccess()) }
13570
}
13671

13772
/**

0 commit comments

Comments
 (0)