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
|
// check if there is base class that is not copyable
|
||||||
for (const Type::BaseInfo &baseInfo : scope->definedType->derivedFrom) {
|
for (const Type::BaseInfo &baseInfo : scope->definedType->derivedFrom) {
|
||||||
if (!baseInfo.type || !baseInfo.type->classScope) {
|
if (!baseInfo.type || !baseInfo.type->classScope) {
|
||||||
u = true;
|
*unknown = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNonCopyable(baseInfo.type->classScope, &u))
|
if (hasNonCopyableBase(baseInfo.type->classScope, unknown))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (const Function &func : baseInfo.type->classScope->functionList) {
|
for (const Function &func : baseInfo.type->classScope->functionList) {
|
||||||
if (func.type != Function::eCopyConstructor)
|
if (func.type != Function::eCopyConstructor)
|
||||||
continue;
|
continue;
|
||||||
if (func.access == AccessControl::Private || func.isDelete())
|
if (func.access == AccessControl::Private || func.isDelete()) {
|
||||||
|
*unknown = false;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*unknown = u;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,12 +366,12 @@ void CheckClass::copyconstructors()
|
||||||
}
|
}
|
||||||
if (!funcCopyCtor || funcCopyCtor->isDefault()) {
|
if (!funcCopyCtor || funcCopyCtor->isDefault()) {
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
if (!isNonCopyable(scope, &unknown) && !unknown)
|
if (!hasNonCopyableBase(scope, &unknown) && !unknown)
|
||||||
noCopyConstructorError(scope, funcCopyCtor, allocatedVars.begin()->second, unknown);
|
noCopyConstructorError(scope, funcCopyCtor, allocatedVars.begin()->second, unknown);
|
||||||
}
|
}
|
||||||
if (!funcOperatorEq || funcOperatorEq->isDefault()) {
|
if (!funcOperatorEq || funcOperatorEq->isDefault()) {
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
if (!isNonCopyable(scope, &unknown) && !unknown)
|
if (!hasNonCopyableBase(scope, &unknown) && !unknown)
|
||||||
noOperatorEqError(scope, funcOperatorEq, allocatedVars.begin()->second, unknown);
|
noOperatorEqError(scope, funcOperatorEq, allocatedVars.begin()->second, unknown);
|
||||||
}
|
}
|
||||||
if (!funcDestructor || funcDestructor->isDefault()) {
|
if (!funcDestructor || funcDestructor->isDefault()) {
|
||||||
|
|
|
@ -71,6 +71,7 @@ private:
|
||||||
TEST_CASE(copyConstructor2); // ticket #4458
|
TEST_CASE(copyConstructor2); // ticket #4458
|
||||||
TEST_CASE(copyConstructor3); // defaulted/deleted
|
TEST_CASE(copyConstructor3); // defaulted/deleted
|
||||||
TEST_CASE(copyConstructor4); // base class with private constructor
|
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(noOperatorEq); // class with memory management should have operator eq
|
||||||
TEST_CASE(noDestructor); // class with memory management should have destructor
|
TEST_CASE(noDestructor); // class with memory management should have destructor
|
||||||
|
|
||||||
|
@ -908,6 +909,30 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void noOperatorEq() {
|
||||||
checkCopyConstructor("struct F {\n"
|
checkCopyConstructor("struct F {\n"
|
||||||
" char* c;\n"
|
" char* c;\n"
|
||||||
|
|
Loading…
Reference in New Issue