Fixed #1465 (false positive: unintialized class member)

This commit is contained in:
Daniel Marjamäki 2010-03-13 20:24:39 +01:00
parent 65ae37de2f
commit 9fe9be1ea9
2 changed files with 29 additions and 6 deletions

View File

@ -235,7 +235,7 @@ void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *va
} }
// Before a new statement there is "[{};)=]" or "else" // Before a new statement there is "[{};)=]" or "else"
if (! Token::Match(ftok, "[{};)=]") && ftok->str() != "else") if (! Token::Match(ftok, "[{};()=]") && ftok->str() != "else")
continue; continue;
// Using the operator= function to initialize all variables.. // Using the operator= function to initialize all variables..
@ -285,18 +285,22 @@ void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *va
continue; continue;
} }
else if (ftok->str() == "if")
continue;
// Calling member function? // Calling member function?
else if (Token::Match(ftok, "%var% (")) else if (Token::Match(ftok, "%var% ("))
{ {
// No recursive calls! // No recursive calls!
if (std::find(callstack.begin(), callstack.end(), ftok->str()) == callstack.end()) if (std::find(callstack.begin(), callstack.end(), ftok->str()) == callstack.end())
{ {
callstack.push_back(ftok->str());
int i = 0; int i = 0;
const Token *ftok2 = _tokenizer->findClassFunction(tok1, classname, ftok->strAt(0), i, isStruct); const Token *ftok2 = _tokenizer->findClassFunction(tok1, classname, ftok->strAt(0), i, isStruct);
if (ftok2) if (ftok2)
{ {
callstack.push_back(ftok->str());
initializeVarList(tok1, ftok2, varlist, classname, callstack, isStruct); initializeVarList(tok1, ftok2, varlist, classname, callstack, isStruct);
callstack.pop_back();
} }
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
{ {
@ -331,16 +335,16 @@ void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *va
// the function is external and it's neither friend nor inherited virtual function. // the function is external and it's neither friend nor inherited virtual function.
// assume all variables that are passed to it are initialized.. // assume all variables that are passed to it are initialized..
unsigned int indentlevel = 0; unsigned int indentlevel2 = 0;
for (tok = ftok->tokAt(2); tok; tok = tok->next()) for (tok = ftok->tokAt(2); tok; tok = tok->next())
{ {
if (tok->str() == "(") if (tok->str() == "(")
++indentlevel; ++indentlevel2;
else if (tok->str() == ")") else if (tok->str() == ")")
{ {
if (indentlevel == 0) if (indentlevel2 == 0)
break; break;
--indentlevel; --indentlevel2;
} }
if (tok->isName()) if (tok->isName())
{ {

View File

@ -52,6 +52,7 @@ private:
TEST_CASE(uninitVarArray1); TEST_CASE(uninitVarArray1);
TEST_CASE(uninitVarArray2); TEST_CASE(uninitVarArray2);
TEST_CASE(uninitVarArray3); TEST_CASE(uninitVarArray3);
TEST_CASE(uninitVarArray4);
TEST_CASE(uninitVarArray2D); TEST_CASE(uninitVarArray2D);
TEST_CASE(uninitMissingFuncDef);// can't expand function in constructor TEST_CASE(uninitMissingFuncDef);// can't expand function in constructor
TEST_CASE(privateCtor1); // If constructor is private.. TEST_CASE(privateCtor1); // If constructor is private..
@ -1185,6 +1186,24 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void uninitVarArray4()
{
checkUninitVar("class John\n"
"{\n"
"private:\n"
" int a[100];\n"
" int b[100];\n"
"\n"
"public:\n"
" John()\n"
" {\n"
" if (snprintf(a,10,\"a\")) { }\n"
" if (snprintf(b,10,\"b\")) { }\n"
" }\n"
"};\n");
ASSERT_EQUALS("", errout.str());
}
void uninitVarArray2D() void uninitVarArray2D()
{ {
checkUninitVar("class John\n" checkUninitVar("class John\n"