Fixed #1148 (improve check: usage of uninitialized variables)
This commit is contained in:
parent
9656379ffb
commit
c3edc5fd89
|
@ -1924,7 +1924,7 @@ private:
|
||||||
if (p)
|
if (p)
|
||||||
vartok = vartok->next();
|
vartok = vartok->next();
|
||||||
declare(checks, vartok, tok, p, false);
|
declare(checks, vartok, tok, p, false);
|
||||||
return vartok->next();
|
return vartok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variable declaration for array..
|
// Variable declaration for array..
|
||||||
|
@ -1932,7 +1932,7 @@ private:
|
||||||
{
|
{
|
||||||
const Token * vartok = tok.next();
|
const Token * vartok = tok.next();
|
||||||
declare(checks, vartok, tok, false, true);
|
declare(checks, vartok, tok, false, true);
|
||||||
return vartok->next()->link()->next();
|
return vartok->next()->link();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Template pointer variable..
|
// Template pointer variable..
|
||||||
|
@ -2222,6 +2222,85 @@ private:
|
||||||
ExecutionPath::bailOutVar(checks, tok.varId());
|
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;
|
return &tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1179,6 +1179,20 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
|
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"
|
checkUninitVar("static int foo(int x)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int i;\n"
|
" int i;\n"
|
||||||
|
|
Loading…
Reference in New Issue