Fixed #1148 (improve check: usage of uninitialized variables)

This commit is contained in:
Daniel Marjamäki 2010-03-28 21:27:06 +02:00
parent 9656379ffb
commit c3edc5fd89
2 changed files with 95 additions and 2 deletions

View File

@ -1924,7 +1924,7 @@ private:
if (p)
vartok = vartok->next();
declare(checks, vartok, tok, p, false);
return vartok->next();
return vartok;
}
// Variable declaration for array..
@ -1932,7 +1932,7 @@ private:
{
const Token * vartok = tok.next();
declare(checks, vartok, tok, false, true);
return vartok->next()->link()->next();
return vartok->next()->link();
}
// Template pointer variable..
@ -2222,6 +2222,85 @@ private:
ExecutionPath::bailOutVar(checks, tok.varId());
}
}
// Parse "for"
if (Token::Match(&tok, "[;{}] for ("))
{
// initialized variables
std::set<unsigned int> varid1;
varid1.insert(0);
// Parse token
const Token *tok2;
// parse setup
for (tok2 = tok.tokAt(3); tok2; tok2 = tok2->next())
{
if (tok2->str() == ";")
break;
if (tok2->varId())
varid1.insert(tok2->varId());
}
// parse condition
if (Token::Match(tok2, "; %var% <|<=|>=|> %num% ;"))
{
// If the variable hasn't been initialized then call "use"
if (varid1.find(tok2->next()->varId()) == varid1.end())
use(foundError, checks, tok2->next());
}
// goto stepcode
tok2 = tok2->next();
while (tok2 && tok2->str() != ";")
tok2 = tok2->next();
// parse the stepcode
if (Token::Match(tok2, "; ++|-- %var% ) {") ||
Token::Match(tok2, "; %var% ++|-- ) {"))
{
// get id of variable..
unsigned int varid = tok2->next()->varId();
if (!varid)
varid = tok2->tokAt(2)->varId();
// Check that the variable hasn't been initialized and
// that it isn't initialized in the body..
if (varid1.find(varid) == varid1.end())
{
unsigned int indentlevel = 0;
for (const Token *tok3 = tok2->tokAt(5); tok3; tok3 = tok3->next())
{
if (tok3->str() == "{")
++indentlevel;
else if (tok3->str() == "}")
{
if (indentlevel == 0)
break;
--indentlevel;
}
if (tok3->varId() == varid)
{
varid = 0; // variable is used.. maybe it's initialized. clear the variable id.
break;
}
}
// If the variable isn't initialized in the body call "use"
if (varid != 0)
{
// goto variable
tok2 = tok2->next();
if (!tok2->varId())
tok2 = tok2->next();
// call "use"
use(foundError, checks, tok2);
}
}
}
}
return &tok;
}

View File

@ -1179,6 +1179,20 @@ private:
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
checkUninitVar("static void foo()\n"
"{\n"
" int i;\n"
" for (int x = 0; i < 10; x++);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
checkUninitVar("static void foo()\n"
"{\n"
" int i;\n"
" for (int x = 0; x < 10; i++);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
checkUninitVar("static int foo(int x)\n"
"{\n"
" int i;\n"