Fixed #2415 (false positive: Member variable not initialized in constructor calling assignment operator)

This commit is contained in:
Robert Reif 2011-01-06 07:56:34 +01:00 committed by Daniel Marjamäki
parent d7e170b3ca
commit 03a484554c
2 changed files with 67 additions and 0 deletions

View File

@ -1574,6 +1574,41 @@ void SymbolDatabase::SpaceInfo::initializeVarList(const Func &func, std::list<st
}
// Calling member function?
else if (Token::simpleMatch(ftok, "operator = ("))
{
// check if member function exists
std::list<Func>::const_iterator it;
for (it = functionList.begin(); it != functionList.end(); ++it)
{
if (ftok->next()->str() == it->tokenDef->str() && it->type != Func::Constructor)
break;
}
// member function found
if (it != functionList.end())
{
// member function has implementation
if (it->hasBody)
{
// initialize variable use list using member function
callstack.push_back(ftok->str());
initializeVarList(*it, callstack);
callstack.pop_back();
}
// there is a called member function, but it has no implementation, so we assume it initializes everything
else
{
assignAllVar();
}
}
// using default operator =, assume everything initialized
else
{
assignAllVar();
}
}
else if (Token::Match(ftok, "%var% (") && ftok->str() != "if")
{
// Passing "this" => assume that everything is initialized

View File

@ -89,6 +89,7 @@ private:
TEST_CASE(uninitSameClassName); // No FP when two classes have the same name
TEST_CASE(uninitFunctionOverload); // No FP when there are overloaded functions
TEST_CASE(uninitJava); // Java: no FP when variable is initialized in declaration
TEST_CASE(uninitVarOperatorEqual); // ticket #2415
TEST_CASE(noConstructor1);
TEST_CASE(noConstructor2);
@ -2706,6 +2707,37 @@ private:
ASSERT_EQUALS("", errout.str());
}
void uninitVarOperatorEqual() // ticket #2415
{
checkUninitVar("struct A {\n"
" int a;\n"
" A() { a=0; }\n"
" A(A const &a) { operator=(a); }\n"
"};");
ASSERT_EQUALS("", errout.str());
checkUninitVar("struct A {\n"
" int a;\n"
" A() { a=0; }\n"
" A(A const &a) { operator=(a); }\n"
" A & operator = (const A & rhs) {\n"
" a = rhs.a;\n"
" return *this;\n"
" }\n"
"};");
ASSERT_EQUALS("", errout.str());
checkUninitVar("struct A {\n"
" int a;\n"
" A() { a=0; }\n"
" A(A const &a) { operator=(a); }\n"
" A & operator = (const A & rhs) {\n"
" return *this;\n"
" }\n"
"};");
ASSERT_EQUALS("[test.cpp:4]: (warning) Member variable 'A::a' is not initialised in the constructor.\n"
"[test.cpp:5]: (warning) Member variable 'A::a' is not assigned a value in 'A::operator='\n", errout.str());
}
void checkNoConstructor(const char code[])
{