Fix noCopyConstructor with multiple inheritance (#3203)
This commit is contained in:
parent
f8dc9862da
commit
1e9687aa8b
|
@ -298,27 +298,27 @@ void CheckClass::checkExplicitConstructors()
|
|||
}
|
||||
}
|
||||
|
||||
static bool isNonCopyable(const Scope *scope, bool *unknown)
|
||||
static bool hasNonCopyableBase(const Scope *scope, bool *unknown)
|
||||
{
|
||||
bool u = false;
|
||||
// check if there is base class that is not copyable
|
||||
for (const Type::BaseInfo &baseInfo : scope->definedType->derivedFrom) {
|
||||
if (!baseInfo.type || !baseInfo.type->classScope) {
|
||||
u = true;
|
||||
*unknown = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isNonCopyable(baseInfo.type->classScope, &u))
|
||||
if (hasNonCopyableBase(baseInfo.type->classScope, unknown))
|
||||
return true;
|
||||
|
||||
for (const Function &func : baseInfo.type->classScope->functionList) {
|
||||
if (func.type != Function::eCopyConstructor)
|
||||
continue;
|
||||
if (func.access == AccessControl::Private || func.isDelete())
|
||||
if (func.access == AccessControl::Private || func.isDelete()) {
|
||||
*unknown = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*unknown = u;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -366,12 +366,12 @@ void CheckClass::copyconstructors()
|
|||
}
|
||||
if (!funcCopyCtor || funcCopyCtor->isDefault()) {
|
||||
bool unknown = false;
|
||||
if (!isNonCopyable(scope, &unknown) && !unknown)
|
||||
if (!hasNonCopyableBase(scope, &unknown) && !unknown)
|
||||
noCopyConstructorError(scope, funcCopyCtor, allocatedVars.begin()->second, unknown);
|
||||
}
|
||||
if (!funcOperatorEq || funcOperatorEq->isDefault()) {
|
||||
bool unknown = false;
|
||||
if (!isNonCopyable(scope, &unknown) && !unknown)
|
||||
if (!hasNonCopyableBase(scope, &unknown) && !unknown)
|
||||
noOperatorEqError(scope, funcOperatorEq, allocatedVars.begin()->second, unknown);
|
||||
}
|
||||
if (!funcDestructor || funcDestructor->isDefault()) {
|
||||
|
|
|
@ -71,6 +71,7 @@ private:
|
|||
TEST_CASE(copyConstructor2); // ticket #4458
|
||||
TEST_CASE(copyConstructor3); // defaulted/deleted
|
||||
TEST_CASE(copyConstructor4); // base class with private constructor
|
||||
TEST_CASE(copyConstructor5); // multiple inheritance
|
||||
TEST_CASE(noOperatorEq); // class with memory management should have operator eq
|
||||
TEST_CASE(noDestructor); // class with memory management should have destructor
|
||||
|
||||
|
@ -908,6 +909,30 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void copyConstructor5() {
|
||||
checkCopyConstructor("class Copyable {};\n"
|
||||
"\n"
|
||||
"class Foo : public Copyable, public UnknownType {\n"
|
||||
"public:\n"
|
||||
" Foo() : m_ptr(new int) {}\n"
|
||||
" ~Foo() { delete m_ptr; }\n"
|
||||
"private:\n"
|
||||
" int* m_ptr;\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkCopyConstructor("class Copyable {};\n"
|
||||
"\n"
|
||||
"class Foo : public UnknownType, public Copyable {\n"
|
||||
"public:\n"
|
||||
" Foo() : m_ptr(new int) {}\n"
|
||||
" ~Foo() { delete m_ptr; }\n"
|
||||
"private:\n"
|
||||
" int* m_ptr;\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void noOperatorEq() {
|
||||
checkCopyConstructor("struct F {\n"
|
||||
" char* c;\n"
|
||||
|
|
Loading…
Reference in New Issue