Skip to content

Commit a31aac3

Browse files
All tests passing for main query
1 parent ba6c2ca commit a31aac3

4 files changed

Lines changed: 105 additions & 44 deletions

File tree

cpp/misra/src/rules/RULE-15-0-1/AnalyzableClass.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ private predicate isUsable(MemberFunction f) {
77

88
private predicate isMemberCustomized(MemberFunction f) {
99
exists(f.getDefinition()) and
10-
not f.isDefaulted()
10+
not f.isDefaulted() and
11+
not f.isDeleted()
1112
}
1213

1314
newtype TSpecialMember =

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

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ predicate isMoveOnly(AnalyzableClass c) {
4242
not c.copyAssignable()
4343
}
4444

45-
predicate unmovable(AnalyzableClass c) {
45+
predicate isUnmovable(AnalyzableClass c) {
4646
not c.moveConstructible() and
4747
not c.moveAssignable() and
4848
not c.copyConstructible() and
@@ -52,55 +52,84 @@ predicate unmovable(AnalyzableClass c) {
5252
predicate isValidCategory(AnalyzableClass c) {
5353
isCopyEnabled(c) or
5454
isMoveOnly(c) or
55-
unmovable(c)
55+
isUnmovable(c)
56+
}
57+
58+
string specialMemberName(TSpecialMember f) {
59+
f = TCopyConstructor() and result = "copy constructor"
60+
or
61+
f = TMoveConstructor() and result = "move constructor"
62+
or
63+
f = TCopyAssignmentOperator() and result = "copy assignment operator"
64+
or
65+
f = TMoveAssignmentOperator() and result = "move assignment operator"
66+
}
67+
68+
predicate violatesCustomizedMoveOrCopyRequirements(AnalyzableClass c, string reason) {
69+
not c.isCustomized(TDestructor()) and
70+
exists(string concatenated |
71+
concatenated =
72+
strictconcat(TSpecialMember f |
73+
not f = TDestructor() and
74+
c.isCustomized(f)
75+
|
76+
specialMemberName(f), ", "
77+
) and
78+
reason = "has customized " + concatenated + ", but does not customize the destructor."
79+
)
5680
}
5781

5882
predicate violatesCustomizedDestructorRequirements(AnalyzableClass c, string reason) {
5983
c.isCustomized(TDestructor()) and
6084
(
6185
c.moveConstructible() and
6286
not c.isCustomized(TMoveConstructor()) and
63-
reason = "Move constructor is not customized"
87+
reason = "has customized the destructor, but does not customize the move constructor."
6488
or
6589
c.moveAssignable() and
6690
not c.isCustomized(TMoveAssignmentOperator()) and
67-
reason = "Move assignment operator is not customized"
91+
reason = "has customized the destructor, but does not customize the move assignment operator."
6892
or
6993
c.copyConstructible() and
7094
not c.isCustomized(TCopyConstructor()) and
71-
reason = "Copy constructor is not customized"
95+
reason = "has customized the destructor, but does not customize the copy constructor."
7296
or
7397
c.copyAssignable() and
7498
not c.isCustomized(TCopyAssignmentOperator()) and
75-
reason = "Copy assignment operator is not customized"
99+
reason = "has customized the destructor, but does not customize the copy assignment operator."
76100
)
77101
}
78102

79-
predicate violatesInheritanceRequirements(AnalyzableClass c) {
103+
predicate isPublicBase(AnalyzableClass c) {
80104
exists(ClassDerivation d |
81105
d.getBaseClass() = c and
82106
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()
91107
)
92108
}
93109

110+
predicate satisfiesInheritanceRequirements(AnalyzableClass c) {
111+
not isPublicBase(c)
112+
or
113+
isUnmovable(c) and
114+
c.getDestructor().isPublic() and
115+
c.getDestructor().isVirtual()
116+
or
117+
c.getDestructor().isProtected() and
118+
not c.getDestructor().isVirtual()
119+
}
120+
94121
from AnalyzableClass c, string message
95122
where
96123
not isExcluded(c, Classes3Package::improperlyProvidedSpecialMemberFunctionsQuery()) and
97124
(
98125
not isValidCategory(c) and
99-
message = "Class does not fall into a valid category (unmovable, move-only, or copy-enabled)."
126+
message = "does not fall into a valid category (isUnmovable, move-only, or copy-enabled)."
127+
or
128+
violatesCustomizedMoveOrCopyRequirements(c, message)
100129
or
101130
violatesCustomizedDestructorRequirements(c, message)
102131
or
103-
violatesInheritanceRequirements(c) and
104-
message = "Class violates inheritance requirements for special member functions."
132+
not satisfiesInheritanceRequirements(c) and
133+
message = "violates inheritance requirements for special member functions."
105134
)
106-
select c, message
135+
select c, "Class '" + c.getName() + "' " + message
Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,30 @@
1-
No expected results have yet been specified
1+
| test.cpp:69:11:69:12 | C2 | Class 'C2' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
2+
| test.cpp:70:11:70:12 | C3 | Class 'C3' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
3+
| test.cpp:72:11:72:12 | C5 | Class 'C5' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
4+
| test.cpp:74:11:74:12 | C7 | Class 'C7' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
5+
| test.cpp:76:11:76:12 | C9 | Class 'C9' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
6+
| test.cpp:77:11:77:13 | C10 | Class 'C10' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
7+
| test.cpp:78:11:78:13 | C11 | Class 'C11' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
8+
| test.cpp:79:11:79:13 | C12 | Class 'C12' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
9+
| test.cpp:80:11:80:13 | C13 | Class 'C13' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
10+
| test.cpp:81:11:81:13 | C14 | Class 'C14' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
11+
| test.cpp:82:11:82:13 | C15 | Class 'C15' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
12+
| test.cpp:100:7:100:21 | PrivateCopyCtor | Class 'PrivateCopyCtor' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
13+
| test.cpp:113:7:113:21 | PrivateMoveCtor | Class 'PrivateMoveCtor' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
14+
| test.cpp:126:7:126:23 | PrivateCopyAssign | Class 'PrivateCopyAssign' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
15+
| test.cpp:139:7:139:23 | PrivateMoveAssign | Class 'PrivateMoveAssign' does not fall into a valid category (isUnmovable, move-only, or copy-enabled). |
16+
| test.cpp:179:7:179:45 | CustomizedCopyCtorDefaultedNonCompliant | Class 'CustomizedCopyCtorDefaultedNonCompliant' has customized copy constructor, but does not customize the destructor. |
17+
| test.cpp:186:7:186:43 | CustomizedCopyCtorDeletedNonCompliant | Class 'CustomizedCopyCtorDeletedNonCompliant' has customized copy constructor, but does not customize the destructor. |
18+
| test.cpp:192:7:192:36 | CustomizedMoveCtorNonCompliant | Class 'CustomizedMoveCtorNonCompliant' has customized move constructor, but does not customize the destructor. |
19+
| test.cpp:198:7:198:38 | CustomizedCopyAssignNonCompliant | Class 'CustomizedCopyAssignNonCompliant' has customized copy assignment operator, but does not customize the destructor. |
20+
| test.cpp:204:7:204:38 | CustomizedMoveAssignNonCompliant | Class 'CustomizedMoveAssignNonCompliant' has customized copy constructor, move assignment operator, move constructor, but does not customize the destructor. |
21+
| test.cpp:211:7:211:39 | MoveOnlyNotCustomizedNonCompliant | Class 'MoveOnlyNotCustomizedNonCompliant' has customized the destructor, but does not customize the move constructor. |
22+
| test.cpp:218:7:218:49 | MoveOnlyAssignableNotCustomizedNonCompliant | Class 'MoveOnlyAssignableNotCustomizedNonCompliant' has customized the destructor, but does not customize the move assignment operator. |
23+
| test.cpp:218:7:218:49 | MoveOnlyAssignableNotCustomizedNonCompliant | Class 'MoveOnlyAssignableNotCustomizedNonCompliant' has customized the destructor, but does not customize the move constructor. |
24+
| test.cpp:249:7:249:43 | CopyEnabledCustomizedDtorNonCompliant | Class 'CopyEnabledCustomizedDtorNonCompliant' has customized the destructor, but does not customize the copy assignment operator. |
25+
| test.cpp:249:7:249:43 | CopyEnabledCustomizedDtorNonCompliant | Class 'CopyEnabledCustomizedDtorNonCompliant' has customized the destructor, but does not customize the copy constructor. |
26+
| test.cpp:249:7:249:43 | CopyEnabledCustomizedDtorNonCompliant | Class 'CopyEnabledCustomizedDtorNonCompliant' has customized the destructor, but does not customize the move assignment operator. |
27+
| test.cpp:249:7:249:43 | CopyEnabledCustomizedDtorNonCompliant | Class 'CopyEnabledCustomizedDtorNonCompliant' has customized the destructor, but does not customize the move constructor. |
28+
| test.cpp:268:7:268:33 | UnmovableBaseNonvirtualDtor | Class 'UnmovableBaseNonvirtualDtor' violates inheritance requirements for special member functions. |
29+
| test.cpp:289:7:289:33 | UnmovablePrivateVirtualDtor | Class 'UnmovablePrivateVirtualDtor' violates inheritance requirements for special member functions. |
30+
| test.cpp:316:7:316:30 | BaseVirtualProtectedDtor | Class 'BaseVirtualProtectedDtor' violates inheritance requirements for special member functions. |

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

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -151,46 +151,48 @@ class PrivateMoveAssign { // NON_COMPLIANT
151151

152152
namespace additional_requirements {
153153

154-
class CustomizedCopyCtorCompliant { // COMPLIANT
154+
// A class with a customized copy constructor requires a customized destructor
155+
class CustomizedMoveCtorCompliant { // COMPLIANT
155156
public:
156-
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCopyCtorCompliant, CUSTOMIZED, DEFAULTED,
157-
DEFAULTED, DEFAULTED, CUSTOMIZED)
157+
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveCtorCompliant, DELETED, CUSTOMIZED,
158+
DELETED, DELETED, CUSTOMIZED)
158159
};
159160

160-
class CustomizedMoveCtorCompliant { // COMPLIANT
161+
class CustomizedCtorsCompliant { // COMPLIANT
161162
public:
162-
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveCtorCompliant, DEFAULTED, CUSTOMIZED,
163-
DEFAULTED, DEFAULTED, CUSTOMIZED)
163+
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCtorsCompliant, CUSTOMIZED, CUSTOMIZED,
164+
DELETED, DELETED, CUSTOMIZED)
164165
};
165166

166-
class CustomizedCopyAssignCompliant { // COMPLIANT
167+
class CustomizedMoveAssignCompliant { // COMPLIANT
167168
public:
168-
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCopyAssignCompliant, DEFAULTED,
169-
DEFAULTED, CUSTOMIZED, DEFAULTED, CUSTOMIZED)
169+
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveAssignCompliant, DELETED, CUSTOMIZED,
170+
DELETED, CUSTOMIZED, CUSTOMIZED)
170171
};
171172

172-
class CustomizedMoveAssignCompliant { // COMPLIANT
173+
class CustomizedAssignsCompliant { // COMPLIANT
173174
public:
174-
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveAssignCompliant, DEFAULTED,
175-
DEFAULTED, DEFAULTED, CUSTOMIZED, CUSTOMIZED)
175+
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedAssignsCompliant, CUSTOMIZED, CUSTOMIZED,
176+
CUSTOMIZED, CUSTOMIZED, CUSTOMIZED)
176177
};
177178

178-
class CustomizedCopyCtorDefaultDtor { // NON_COMPLIANT
179+
class CustomizedCopyCtorDefaultedNonCompliant { // NON_COMPLIANT
179180
public:
180-
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCopyCtorDefaultDtor, CUSTOMIZED,
181-
DEFAULTED, DEFAULTED, DEFAULTED, DEFAULTED)
181+
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCopyCtorDefaultedNonCompliant,
182+
CUSTOMIZED, DEFAULTED, DEFAULTED, DEFAULTED,
183+
DEFAULTED)
182184
};
183185

184-
class CustomizedCopyCtorDeletedDtor { // NON_COMPLIANT
186+
class CustomizedCopyCtorDeletedNonCompliant { // NON_COMPLIANT
185187
public:
186-
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCopyCtorDeletedDtor, CUSTOMIZED,
188+
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedCopyCtorDeletedNonCompliant, CUSTOMIZED,
187189
DEFAULTED, DEFAULTED, DEFAULTED, DELETED)
188190
};
189191

190192
class CustomizedMoveCtorNonCompliant { // NON_COMPLIANT
191193
public:
192-
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveCtorNonCompliant, CUSTOMIZED,
193-
DEFAULTED, DEFAULTED, DEFAULTED, DEFAULTED)
194+
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveCtorNonCompliant, DEFAULTED,
195+
CUSTOMIZED, DEFAULTED, DEFAULTED, DEFAULTED)
194196
};
195197

196198
class CustomizedCopyAssignNonCompliant { // NON_COMPLIANT
@@ -201,8 +203,8 @@ class CustomizedCopyAssignNonCompliant { // NON_COMPLIANT
201203

202204
class CustomizedMoveAssignNonCompliant { // NON_COMPLIANT
203205
public:
204-
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveAssignNonCompliant, DEFAULTED,
205-
DEFAULTED, DEFAULTED, CUSTOMIZED, DEFAULTED)
206+
DEFINE_ALL_SPECIAL_MEMBERS(CustomizedMoveAssignNonCompliant, CUSTOMIZED,
207+
CUSTOMIZED, DEFAULTED, CUSTOMIZED, DEFAULTED)
206208
};
207209

208210
// Move-only with a customized dtor requires customized move operations.
@@ -302,7 +304,7 @@ class BaseProtectedDtor { // COMPLIANT
302304
public:
303305
COPY_CTOR(BaseProtectedDtor) = default;
304306
MOVE_CTOR(BaseProtectedDtor) = default;
305-
COPY_ASSIGN(BaseProtectedDtor) = default;
307+
COPY_ASSIGN(BaseProtectedDtor) = delete;
306308
MOVE_ASSIGN(BaseProtectedDtor) = delete;
307309

308310
protected:
@@ -315,7 +317,7 @@ class BaseVirtualProtectedDtor { // NON_COMPLIANT
315317
public:
316318
COPY_CTOR(BaseVirtualProtectedDtor) = default;
317319
MOVE_CTOR(BaseVirtualProtectedDtor) = default;
318-
COPY_ASSIGN(BaseVirtualProtectedDtor) = default;
320+
COPY_ASSIGN(BaseVirtualProtectedDtor) = delete;
319321
MOVE_ASSIGN(BaseVirtualProtectedDtor) = delete;
320322

321323
protected:

0 commit comments

Comments
 (0)