Fixed #643 (Member variable not initialized not detected if any unknown function called)

This commit is contained in:
Daniel Marjamäki 2010-01-22 18:51:25 +01:00
parent 9f853cb164
commit 59de7934b7
2 changed files with 70 additions and 7 deletions

View File

@ -291,14 +291,56 @@ void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *va
initializeVarList(tok1, ftok2, varlist, classname, callstack, isStruct); initializeVarList(tok1, ftok2, varlist, classname, callstack, isStruct);
} }
else // there is a called member function, but it is not defined where we can find it, so we assume it initializes everything else // there is a called member function, but it is not defined where we can find it, so we assume it initializes everything
{
// check if the function is part of this class..
const Token *tok = Token::findmatch(_tokenizer->tokens(), (std::string("class ") + classname + " {").c_str());
for (tok = tok ? tok->tokAt(3) : 0; tok; tok = tok->next())
{
if (tok->str() == "{")
{
tok = tok->link();
if (!tok)
break;
}
else if (tok->str() == "}")
{
break;
}
else if (tok->str() == ftok->str() || tok->str() == "friend")
{
tok = 0;
break;
}
}
// bail out..
if (!tok)
{ {
for (Var *var = varlist; var; var = var->next) for (Var *var = varlist; var; var = var->next)
var->init = true; var->init = true;
break; break;
}
// we don't report this, as somewhere along the line we hope that the class and member function // the function is external and it's neither friend nor inherited virtual function.
// are checked together. It is possible that this will not be the case (where there are enough // assume all variables that are passed to it are initialized..
// nested functions defined in different files), but that isn't really likely. unsigned int indentlevel = 0;
for (tok = ftok->tokAt(2); tok; tok = tok->next())
{
if (tok->str() == "(")
++indentlevel;
else if (tok->str() == ")")
{
if (indentlevel == 0)
break;
--indentlevel;
}
if (tok->isName())
{
for (Var *var = varlist; var; var = var->next)
var->init |= bool(tok->str() == var->name);
}
}
continue;
} }
} }
} }

View File

@ -1142,6 +1142,27 @@ private:
"};\n"); "};\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// Unknown non-member function (friend class)
checkUninitVar("class Fred\n"
"{\n"
"public:\n"
" Fred() { Init(); }\n"
"private:\n"
" friend ABC;\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
// Unknown non-member function (is Init a virtual function?)
checkUninitVar("class Fred : private ABC\n"
"{\n"
"public:\n"
" Fred() { Init(); }\n"
"private:\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
// Unknown non-member function // Unknown non-member function
checkUninitVar("class Fred\n" checkUninitVar("class Fred\n"
"{\n" "{\n"
@ -1150,7 +1171,7 @@ private:
"private:\n" "private:\n"
" int i;\n" " int i;\n"
"};\n"); "};\n");
TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str());
} }
void uninitVarEnum() void uninitVarEnum()