Skip to content

Commit ba6c2ca

Browse files
First implementation
1 parent a31cf70 commit ba6c2ca

3 files changed

Lines changed: 172 additions & 3 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import cpp
2+
3+
private predicate isUsable(MemberFunction f) {
4+
not f.isDeleted() and
5+
f.isPublic()
6+
}
7+
8+
private predicate isMemberCustomized(MemberFunction f) {
9+
exists(f.getDefinition()) and
10+
not f.isDefaulted()
11+
}
12+
13+
newtype TSpecialMember =
14+
TMoveConstructor() or
15+
TMoveAssignmentOperator() or
16+
TCopyConstructor() or
17+
TCopyAssignmentOperator() or
18+
TDestructor()
19+
20+
class AnalyzableClass extends Class {
21+
MoveConstructor moveCtor;
22+
MoveAssignmentOperator moveAssign;
23+
CopyConstructor copyCtor;
24+
CopyAssignmentOperator copyAssign;
25+
Destructor dtor;
26+
27+
AnalyzableClass() {
28+
moveCtor = this.getAConstructor() and
29+
copyCtor = this.getAConstructor() and
30+
moveAssign = this.getAMemberFunction() and
31+
copyAssign = this.getAMemberFunction() and
32+
dtor = this.getDestructor()
33+
}
34+
35+
predicate exposes(TSpecialMember m) {
36+
m instanceof TMoveConstructor and moveConstructible()
37+
or
38+
m instanceof TMoveAssignmentOperator and moveAssignable()
39+
or
40+
m instanceof TCopyConstructor and copyConstructible()
41+
or
42+
m instanceof TCopyAssignmentOperator and copyAssignable()
43+
or
44+
m instanceof TDestructor and destructible()
45+
}
46+
47+
predicate moveConstructible() { isUsable(moveCtor) }
48+
49+
predicate copyConstructible() { isUsable(copyCtor) }
50+
51+
predicate moveAssignable() { isUsable(moveAssign) }
52+
53+
predicate copyAssignable() { isUsable(copyAssign) }
54+
55+
predicate destructible() { isUsable(dtor) }
56+
57+
predicate isCustomized(TSpecialMember s) {
58+
s instanceof TMoveConstructor and isMemberCustomized(moveCtor)
59+
or
60+
s instanceof TMoveAssignmentOperator and isMemberCustomized(moveAssign)
61+
or
62+
s instanceof TCopyConstructor and isMemberCustomized(copyCtor)
63+
or
64+
s instanceof TCopyAssignmentOperator and isMemberCustomized(copyAssign)
65+
or
66+
s instanceof TDestructor and isMemberCustomized(dtor)
67+
}
68+
}

cpp/misra/src/rules/RULE-15-0-1/ImproperlyProvidedSpecialMemberFunctions.ql

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,91 @@
1616

1717
import cpp
1818
import codingstandards.cpp.misra
19+
import AnalyzableClass
1920

20-
from
21+
predicate isCopyEnabled(AnalyzableClass c) {
22+
c.moveConstructible() and
23+
not c.moveAssignable() and
24+
c.copyConstructible() and
25+
not c.copyAssignable()
26+
or
27+
c.moveConstructible() and
28+
c.moveAssignable() and
29+
c.copyConstructible() and
30+
c.copyAssignable()
31+
}
32+
33+
predicate isMoveOnly(AnalyzableClass c) {
34+
c.moveConstructible() and
35+
not c.moveAssignable() and
36+
not c.copyConstructible() and
37+
not c.copyAssignable()
38+
or
39+
c.moveConstructible() and
40+
c.moveAssignable() and
41+
not c.copyConstructible() and
42+
not c.copyAssignable()
43+
}
44+
45+
predicate unmovable(AnalyzableClass c) {
46+
not c.moveConstructible() and
47+
not c.moveAssignable() and
48+
not c.copyConstructible() and
49+
not c.copyAssignable()
50+
}
51+
52+
predicate isValidCategory(AnalyzableClass c) {
53+
isCopyEnabled(c) or
54+
isMoveOnly(c) or
55+
unmovable(c)
56+
}
57+
58+
predicate violatesCustomizedDestructorRequirements(AnalyzableClass c, string reason) {
59+
c.isCustomized(TDestructor()) and
60+
(
61+
c.moveConstructible() and
62+
not c.isCustomized(TMoveConstructor()) and
63+
reason = "Move constructor is not customized"
64+
or
65+
c.moveAssignable() and
66+
not c.isCustomized(TMoveAssignmentOperator()) and
67+
reason = "Move assignment operator is not customized"
68+
or
69+
c.copyConstructible() and
70+
not c.isCustomized(TCopyConstructor()) and
71+
reason = "Copy constructor is not customized"
72+
or
73+
c.copyAssignable() and
74+
not c.isCustomized(TCopyAssignmentOperator()) and
75+
reason = "Copy assignment operator is not customized"
76+
)
77+
}
78+
79+
predicate violatesInheritanceRequirements(AnalyzableClass c) {
80+
exists(ClassDerivation d |
81+
d.getBaseClass() = c and
82+
d.hasSpecifier("public")
83+
) and
84+
(
85+
isMoveOnly(c) and
86+
c.getDestructor().isPublic() and
87+
c.getDestructor().isVirtual()
88+
or
89+
c.getDestructor().isProtected() and
90+
not c.getDestructor().isVirtual()
91+
)
92+
}
93+
94+
from AnalyzableClass c, string message
2195
where
22-
not isExcluded(x, Classes3Package::improperlyProvidedSpecialMemberFunctionsQuery()) and
23-
select
96+
not isExcluded(c, Classes3Package::improperlyProvidedSpecialMemberFunctionsQuery()) and
97+
(
98+
not isValidCategory(c) and
99+
message = "Class does not fall into a valid category (unmovable, move-only, or copy-enabled)."
100+
or
101+
violatesCustomizedDestructorRequirements(c, message)
102+
or
103+
violatesInheritanceRequirements(c) and
104+
message = "Class violates inheritance requirements for special member functions."
105+
)
106+
select c, message

cpp/misra/test/rules/RULE-15-0-1/test.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,94 +152,112 @@ class PrivateMoveAssign { // NON_COMPLIANT
152152
namespace additional_requirements {
153153

154154
class CustomizedCopyCtorCompliant { // COMPLIANT
155+
public:
155156
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCopyCtorCompliant, CUSTOMIZED, DEFAULTED,
156157
DEFAULTED, DEFAULTED, CUSTOMIZED)
157158
};
158159

159160
class CustomizedMoveCtorCompliant { // COMPLIANT
161+
public:
160162
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveCtorCompliant, DEFAULTED, CUSTOMIZED,
161163
DEFAULTED, DEFAULTED, CUSTOMIZED)
162164
};
163165

164166
class CustomizedCopyAssignCompliant { // COMPLIANT
167+
public:
165168
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCopyAssignCompliant, DEFAULTED,
166169
DEFAULTED, CUSTOMIZED, DEFAULTED, CUSTOMIZED)
167170
};
168171

169172
class CustomizedMoveAssignCompliant { // COMPLIANT
173+
public:
170174
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveAssignCompliant, DEFAULTED,
171175
DEFAULTED, DEFAULTED, CUSTOMIZED, CUSTOMIZED)
172176
};
173177

174178
class CustomizedCopyCtorDefaultDtor { // NON_COMPLIANT
179+
public:
175180
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCopyCtorDefaultDtor, CUSTOMIZED,
176181
DEFAULTED, DEFAULTED, DEFAULTED, DEFAULTED)
177182
};
178183

179184
class CustomizedCopyCtorDeletedDtor { // NON_COMPLIANT
185+
public:
180186
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCopyCtorDeletedDtor, CUSTOMIZED,
181187
DEFAULTED, DEFAULTED, DEFAULTED, DELETED)
182188
};
183189

184190
class CustomizedMoveCtorNonCompliant { // NON_COMPLIANT
191+
public:
185192
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveCtorNonCompliant, CUSTOMIZED,
186193
DEFAULTED, DEFAULTED, DEFAULTED, DEFAULTED)
187194
};
188195

189196
class CustomizedCopyAssignNonCompliant { // NON_COMPLIANT
197+
public:
190198
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCopyAssignNonCompliant, DEFAULTED,
191199
DEFAULTED, CUSTOMIZED, DEFAULTED, DEFAULTED)
192200
};
193201

194202
class CustomizedMoveAssignNonCompliant { // NON_COMPLIANT
203+
public:
195204
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveAssignNonCompliant, DEFAULTED,
196205
DEFAULTED, DEFAULTED, CUSTOMIZED, DEFAULTED)
197206
};
198207

199208
// Move-only with a customized dtor requires customized move operations.
200209
class MoveOnlyNotCustomizedNonCompliant { // NON_COMPLIANT
210+
public:
201211
DEFINE_ALL_SPECIAL_MEMBERS(MoveOnlyNotCustomizedNonCompliant, DELETED,
202212
DEFAULTED, DELETED, DELETED, CUSTOMIZED)
203213
};
204214

205215
// Move-only with a customized dtor requires customized move operations.
206216
class MoveOnlyAssignableNotCustomizedNonCompliant { // NON_COMPLIANT
217+
public:
207218
DEFINE_ALL_SPECIAL_MEMBERS(MoveOnlyAssignableNotCustomizedNonCompliant,
208219
DELETED, DEFAULTED, DELETED, DEFAULTED, CUSTOMIZED)
209220
};
210221

211222
class MoveOnlyCustomizedCompliant { // COMPLIANT -- customized move
223+
public:
212224
DEFINE_ALL_SPECIAL_MEMBERS(MoveOnlyCustomizedCompliant, DELETED, CUSTOMIZED,
213225
DELETED, DELETED, CUSTOMIZED)
214226
};
215227

216228
class MoveOnlyAssignableCustomizedCompliant { // COMPLIANT -- customized move
229+
public:
217230
DEFINE_ALL_SPECIAL_MEMBERS(MoveOnlyAssignableCustomizedCompliant, DELETED,
218231
CUSTOMIZED, DELETED, CUSTOMIZED, CUSTOMIZED)
219232
};
220233

221234
class MoveOnlyNotCustomizedCompliant { // COMPLIANT -- default dtor
235+
public:
222236
DEFINE_ALL_SPECIAL_MEMBERS(MoveOnlyNotCustomizedCompliant, DELETED, DEFAULTED,
223237
DELETED, DELETED, DEFAULTED)
224238
};
225239

226240
class MoveOnlyAssignableNotCustomizedCompliant { // COMPLIANT -- default dtor
241+
public:
227242
DEFINE_ALL_SPECIAL_MEMBERS(MoveOnlyAssignableNotCustomizedCompliant, DELETED,
228243
DEFAULTED, DELETED, DEFAULTED, DEFAULTED)
229244
};
230245

231246
// Copy-enabled with customized dtor requires customized copy and move
232247
class CopyEnabledCustomizedDtorNonCompliant { // NON_COMPLIANT
248+
public:
233249
DEFINE_ALL_SPECIAL_MEMBERS(CopyEnabledCustomizedDtorNonCompliant, DEFAULTED,
234250
DEFAULTED, DEFAULTED, DEFAULTED, CUSTOMIZED)
235251
};
236252

237253
class CopyEnabledNonCustomizedDtorCompliant { // COMPLIANT
254+
public:
238255
DEFINE_ALL_SPECIAL_MEMBERS(CopyEnabledNonCustomizedDtorCompliant, DEFAULTED,
239256
DEFAULTED, DEFAULTED, DEFAULTED, DEFAULTED)
240257
};
241258

242259
class CopyEnabledCustomizedDtorCompliant { // COMPLIANT
260+
public:
243261
DEFINE_ALL_SPECIAL_MEMBERS(CopyEnabledCustomizedDtorCompliant, CUSTOMIZED,
244262
CUSTOMIZED, CUSTOMIZED, CUSTOMIZED, CUSTOMIZED)
245263
};

0 commit comments

Comments
 (0)