Fixed #3836 (False positive: variable not initialized in copy constructor/operator (attached example code)

This commit is contained in:
Daniel Marjamäki 2012-09-22 08:16:16 +02:00
parent 6c25f3662e
commit a65f427195
2 changed files with 16 additions and 24 deletions

View File

@ -270,17 +270,20 @@ void CheckClass::noCopyConstructorError(const Token *tok, const std::string &cla
bool CheckClass::canNotCopy(const Scope *scope) bool CheckClass::canNotCopy(const Scope *scope)
{ {
std::list<Function>::const_iterator func; std::list<Function>::const_iterator func;
bool privateAssign = false; bool constructor = false;
bool privateCopy = false; bool publicAssign = false;
bool publicCopy = false;
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
if (func->type == Function::eCopyConstructor && func->access == Private) if (func->type == Function::eConstructor || func->type == Function::eCopyConstructor)
privateCopy = true; constructor = true;
else if (func->type == Function::eOperatorEqual && func->access == Private) if (func->type == Function::eCopyConstructor && func->access == Public)
privateAssign = true; publicCopy = true;
else if (func->type == Function::eOperatorEqual && func->access == Public)
publicAssign = true;
} }
return privateAssign && privateCopy; return constructor && !(publicAssign | publicCopy);
} }
void CheckClass::assignVar(const std::string &varname, const Scope *scope, std::vector<Usage> &usage) void CheckClass::assignVar(const std::string &varname, const Scope *scope, std::vector<Usage> &usage)

View File

@ -739,8 +739,9 @@ private:
"A::B::B(int x){}\n" "A::B::B(int x){}\n"
"A::B::C::C(int y){}\n" "A::B::C::C(int y){}\n"
"A::B::C::D::D(int z){}\n"); "A::B::C::D::D(int z){}\n");
// Note that the example code is not compilable. The A constructor must
// explicitly initialize A::b. A warning for A::b is not necessary.
ASSERT_EQUALS("[test.cpp:20]: (warning) Member variable 'A::a' is not initialized in the constructor.\n" ASSERT_EQUALS("[test.cpp:20]: (warning) Member variable 'A::a' is not initialized in the constructor.\n"
"[test.cpp:20]: (warning) Member variable 'A::b' is not initialized in the constructor.\n"
"[test.cpp:21]: (warning) Member variable 'B::b' is not initialized in the constructor.\n" "[test.cpp:21]: (warning) Member variable 'B::b' is not initialized in the constructor.\n"
"[test.cpp:22]: (warning) Member variable 'C::c' is not initialized in the constructor.\n" "[test.cpp:22]: (warning) Member variable 'C::c' is not initialized in the constructor.\n"
"[test.cpp:23]: (warning) Member variable 'D::d' is not initialized in the constructor.\n", errout.str()); "[test.cpp:23]: (warning) Member variable 'D::d' is not initialized in the constructor.\n", errout.str());
@ -768,8 +769,9 @@ private:
"A::B::B(int x){}\n" "A::B::B(int x){}\n"
"A::B::C::C(int y){}\n" "A::B::C::C(int y){}\n"
"A::B::C::D::D(const A::B::C::D & d){}\n"); "A::B::C::D::D(const A::B::C::D & d){}\n");
// Note that the example code is not compilable. The A constructor must
// explicitly initialize A::b. A warning for A::b is not necessary.
ASSERT_EQUALS("[test.cpp:20]: (warning) Member variable 'A::a' is not initialized in the constructor.\n" ASSERT_EQUALS("[test.cpp:20]: (warning) Member variable 'A::a' is not initialized in the constructor.\n"
"[test.cpp:20]: (warning) Member variable 'A::b' is not initialized in the constructor.\n"
"[test.cpp:21]: (warning) Member variable 'B::b' is not initialized in the constructor.\n" "[test.cpp:21]: (warning) Member variable 'B::b' is not initialized in the constructor.\n"
"[test.cpp:22]: (warning) Member variable 'C::c' is not initialized in the constructor.\n" "[test.cpp:22]: (warning) Member variable 'C::c' is not initialized in the constructor.\n"
"[test.cpp:23]: (warning) Member variable 'D::d' is not initialized in the constructor.\n", errout.str()); "[test.cpp:23]: (warning) Member variable 'D::d' is not initialized in the constructor.\n", errout.str());
@ -798,8 +800,9 @@ private:
"A::B::B(int x){}\n" "A::B::B(int x){}\n"
"A::B::C::C(int y){}\n" "A::B::C::C(int y){}\n"
"A::B::C::D::D(const A::B::C::D::E & e){}\n"); "A::B::C::D::D(const A::B::C::D::E & e){}\n");
// Note that the example code is not compilable. The A constructor must
// explicitly initialize A::b. A warning for A::b is not necessary.
ASSERT_EQUALS("[test.cpp:21]: (warning) Member variable 'A::a' is not initialized in the constructor.\n" ASSERT_EQUALS("[test.cpp:21]: (warning) Member variable 'A::a' is not initialized in the constructor.\n"
"[test.cpp:21]: (warning) Member variable 'A::b' is not initialized in the constructor.\n"
"[test.cpp:22]: (warning) Member variable 'B::b' is not initialized in the constructor.\n" "[test.cpp:22]: (warning) Member variable 'B::b' is not initialized in the constructor.\n"
"[test.cpp:23]: (warning) Member variable 'C::c' is not initialized in the constructor.\n" "[test.cpp:23]: (warning) Member variable 'C::c' is not initialized in the constructor.\n"
"[test.cpp:24]: (warning) Member variable 'D::d' is not initialized in the constructor.\n", errout.str()); "[test.cpp:24]: (warning) Member variable 'D::d' is not initialized in the constructor.\n", errout.str());
@ -1430,20 +1433,6 @@ private:
" Altren value;\n" " Altren value;\n"
"};"); "};");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("struct Altren\n"
"{\n"
" explicit Altren(int _a) : value(0) { }\n"
" int value;\n"
"};\n"
"class A\n"
"{\n"
"public:\n"
" A() { }\n"
"private:\n"
" Altren value;\n"
"};");
ASSERT_EQUALS("[test.cpp:9]: (warning) Member variable 'A::value' is not initialized in the constructor.\n", errout.str());
} }
void uninitVar19() { // ticket #2792 void uninitVar19() { // ticket #2792