-
Notifications
You must be signed in to change notification settings - Fork 76
Expand file tree
/
Copy pathMemberFunctionsRefqualified.ql
More file actions
119 lines (110 loc) · 3.94 KB
/
MemberFunctionsRefqualified.ql
File metadata and controls
119 lines (110 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/**
* @id cpp/misra/member-functions-refqualified
* @name RULE-6-8-4: Member functions returning references to their object should be refqualified appropriately
* @description Member functions that return references to temporary objects (or subobjects) can
* lead to dangling pointers.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-6-8-4
* correctness
* scope/single-translation-unit
* external/misra/enforcement/decidable
* external/misra/obligation/advisory
*/
import cpp
import codingstandards.cpp.misra
import codingstandards.cpp.types.Compatible
import codingstandards.cpp.Operator
import codingstandards.cpp.types.Pointers
import codingstandards.cpp.lifetimes.CppObjects
class MembersReturningPointerOrRef extends MemberFunction {
MembersReturningPointerOrRef() { this.getType() instanceof PointerLikeType }
}
abstract class MembersReturningObjectOrSubobject extends MembersReturningPointerOrRef {
string toString() { result = "Members returning object or subobject" }
}
/**
* Members that have an explicit `this` access within their return statement.
*/
class MembersReturningObject extends MembersReturningObjectOrSubobject {
MembersReturningObject() {
exists(ReturnStmt r, ThisExpr t |
r.getEnclosingFunction() = this and
(
//direct access only
r.getAChild() = t
or
//or one level of indirection
exists(PointerDereferenceExpr p |
p.getAChild() = t and
r.getAChild() = p
)
) and
t.getActualType().stripType() = this.getDeclaringType()
)
}
}
/**
* Members that have an explicit subobject access within their return statement.
*
* Specifically, this captures when the return is a reference or pointer
* to a subobject.
*/
class MembersReturningSubObject extends MembersReturningObjectOrSubobject {
MembersReturningSubObject() {
exists(ReturnStmt r, FieldAccess access, Expr e |
r.getEnclosingFunction() = this and
//direct access only
r.getAChild() = e and
(
//pointer or reference to pointer subobject returned
e = getASubobjectAccessOfPointee(access) and
(e.getType() instanceof PointerType or e.getType() instanceof ReferenceType)
or
//reference to subobject returned
(this.getType() instanceof ReferenceType or e.getType() instanceof ReferenceType) and
not access.getTarget().getType() instanceof PointerType
)
)
}
}
predicate relevantTypes(Type a, Type b) {
exists(MembersReturningObjectOrSubobject f, MemberFunction overload |
f.getAnOverload() = overload and
exists(int i |
f.getParameter(i).getType() = a and
overload.getParameter(i).getType() = b
)
)
}
class AppropriatelyQualified extends MembersReturningObjectOrSubobject {
AppropriatelyQualified() {
//non-const-lvalue-ref-qualified
this.isLValueRefQualified() and
this.getType().(PointerLikeType).pointsToNonConst()
or
//const-lvalue-ref-qualified
this.isLValueRefQualified() and
this.getType().(PointerLikeType).pointsToConst() and
//and overload exists that is rvalue-ref-qualified
exists(MemberFunction overload |
this.getAnOverload() = overload and
overload.isRValueRefQualified() and
//and has same param list
forall(int i | exists([this, overload].getParameter(i)) |
TypeEquivalence<TypesCompatibleConfig, relevantTypes/2>::equalTypes(this.getParameter(i)
.getType(), overload.getParameter(i).getType())
)
)
}
}
class DefaultedAssignmentOperator extends AssignmentOperator {
DefaultedAssignmentOperator() { this.isDefaulted() }
}
from MembersReturningObjectOrSubobject f
where
not isExcluded(f, Declarations5Package::memberFunctionsRefqualifiedQuery()) and
not f instanceof AppropriatelyQualified and
not f instanceof DefaultedAssignmentOperator
select f, "Member function is not properly ref qualified."