forked from github/codeql-coding-standards
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMemberFunctionConstIfPossible.ql
More file actions
126 lines (115 loc) · 3.61 KB
/
MemberFunctionConstIfPossible.ql
File metadata and controls
126 lines (115 loc) · 3.61 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
120
121
122
123
124
125
126
/**
* @id cpp/autosar/member-function-const-if-possible
* @name M9-3-3: A member function shall be made const where possible
* @description Using `const` specifiers for member functions where possible prevents unintentional
* data modification (and therefore unintentional program behaviour).
* @kind problem
* @precision high
* @problem.severity warning
* @tags external/autosar/id/m9-3-3
* correctness
* external/autosar/allocated-target/implementation
* external/autosar/enforcement/automated
* external/autosar/obligation/required
*/
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.SideEffect
/**
* `Declaration` is declared in `Class` c
* or any of c's parents
*/
predicate belongsToClass(Declaration m, Class c) {
m.getDeclaringType() = c
or
exists(Class anyParent |
m.getDeclaringType() = anyParent and
anyParent.getADerivedClass+() = c
)
}
/**
* `MemberFunction`s that are not const
*/
class NonConstMemberFunction extends MemberFunction {
NonConstMemberFunction() { not this.hasSpecifier("const") }
}
/**
* `MemberFunction`s that are not const
* and not `Constructor`s ect as const constructors are
* not a thing in cpp
* also not static because there is no `this` in
* static `MemberFunction`
*/
class ConstMemberFunctionCandidate extends NonConstMemberFunction {
ConstMemberFunctionCandidate() {
//can't be const if already static
not this.isStatic() and
//leave compiler generateds and operators and constructors alone
not this.isCompilerGenerated() and
not this instanceof Constructor and
not this instanceof Destructor and
not this instanceof Operator and
//less interested in MemberFunctions with no definition
this.hasDefinition()
}
/**
* A `MemberVariable` is modified in this `MemberFunction`
* directly
*/
predicate modifiesMemberData() {
exists(VariableEffect e, NonStaticMemberVariable v |
e.getTarget() = v and
this = e.getEnclosingFunction() and
belongsToClass(v, this.getDeclaringType())
)
}
/**
* Calls a `MemberFunction` that it owns that is nonconst
*/
predicate callsNonConstOwnMember() {
exists(NonConstMemberFunction f |
//omit recursive functions
not f = this and
belongsToClass(f, this.getDeclaringType()) and
f.getACallToThisFunction().getEnclosingFunction() = this
)
}
/**
* Calls any nonconst `MemberFunction` that its `MemberVariable`s own
*/
predicate callsNonConstFromMemberVariable() {
exists(NonConstMemberFunction f, MemberVariable m |
belongsToClass(m, f.getDeclaringType()) and
belongsToClass(f, m.getDeclaringType()) and
f.getACallToThisFunction().getEnclosingFunction() = this
)
}
/**
* `ThisExpr`s that are on left hand side
* of `AssignExpr`s
* example: `*this = *i;`
*/
predicate modifiesThis() { exists(AssignExprToThis e | e.getEnclosingFunction() = this) }
}
class AssignExprToThis extends AssignExpr {
AssignExprToThis() {
exists(ThisExpr t | this.getLValue().(PointerDereferenceExpr).getOperand() = t)
}
}
/**
* A nonstatic `MemberVariable`
*/
class NonStaticMemberVariable extends MemberVariable {
NonStaticMemberVariable() { not this.isStatic() }
}
from ConstMemberFunctionCandidate f
where
not isExcluded(f, ConstPackage::memberFunctionConstIfPossibleQuery()) and
not f.modifiesMemberData() and
not f.modifiesThis() and
not f.callsNonConstOwnMember() and
not f.callsNonConstFromMemberVariable() and
not f.isOverride() and
not f.isFinal() and
not f.isDeleted()
select f, "Member function can be declared as const."