Skip to content

Commit 42100fd

Browse files
committed
CheckClass: Better handling of non-copyable classes in the noCopyConstructor check
1 parent f0646d3 commit 42100fd

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

lib/checkclass.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,27 @@ void CheckClass::checkExplicitConstructors()
275275
}
276276
}
277277

278+
static bool isNonCopyable(const Scope *scope, bool *unknown)
279+
{
280+
bool u = false;
281+
// check if there is base class that is not copyable
282+
for (const Type::BaseInfo &baseInfo : scope->definedType->derivedFrom) {
283+
if (!baseInfo.type) {
284+
u = true;
285+
continue;
286+
}
287+
288+
for (const Function &func : baseInfo.type->classScope->functionList) {
289+
if (func.type != Function::eCopyConstructor)
290+
continue;
291+
if (func.access == Private || func.isDelete())
292+
return true;
293+
}
294+
}
295+
*unknown = u;
296+
return false;
297+
}
298+
278299
void CheckClass::copyconstructors()
279300
{
280301
if (!_settings->isEnabled(Settings::STYLE))
@@ -317,9 +338,11 @@ void CheckClass::copyconstructors()
317338
else if (func.type == Function::eDestructor)
318339
hasDestructor = true;
319340
}
320-
bool derived = !scope->definedType->derivedFrom.empty();
321-
if (!hasCopyCtor && !derived)
322-
noCopyConstructorError(scope, derived);
341+
if (!hasCopyCtor) {
342+
bool unknown = false;
343+
if (!isNonCopyable(scope, &unknown))
344+
noCopyConstructorError(scope, unknown);
345+
}
323346
if (!hasOperatorEq)
324347
noOperatorEqError(scope);
325348
if (!hasDestructor)

test/testclass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ class TestClass : public TestFixture {
735735
" ~F();\n"
736736
" F& operator=(const F&f);\n"
737737
"};");
738-
ASSERT_EQUALS("", errout.str());
738+
ASSERT_EQUALS("[test.cpp:1]: (style, inconclusive) class 'F' does not have a copy constructor which is recommended since the class contains a pointer to allocated memory.\n", errout.str());
739739

740740
checkCopyConstructor("class E { E(E&); };\n" // non-copyable
741741
"class F : E\n"
@@ -758,7 +758,7 @@ class TestClass : public TestFixture {
758758
" ~F();\n"
759759
" F& operator=(const F&f);\n"
760760
"};");
761-
TODO_ASSERT_EQUALS("[test.cpp:2]: (style) 'class F' does not have a copy constructor which is recommended since the class contains a pointer to allocated memory.\n", "", errout.str());
761+
ASSERT_EQUALS("[test.cpp:2]: (style) class 'F' does not have a copy constructor which is recommended since the class contains a pointer to allocated memory.\n", errout.str());
762762

763763
checkCopyConstructor("class F {\n"
764764
" char *p;\n"

0 commit comments

Comments
 (0)