Fixed #1465 (false positive: unintialized class member)
This commit is contained in:
parent
65ae37de2f
commit
9fe9be1ea9
|
@ -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())
|
||||||
{
|
{
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue