ExecutionPath: Better handling of 'FOREACH (..) {}'

This commit is contained in:
Daniel Marjamäki 2010-05-30 09:00:18 +02:00
parent f41334e58a
commit ab41879246
2 changed files with 22 additions and 13 deletions

View File

@ -158,24 +158,24 @@ static void checkExecutionPaths_(const Token *tok, std::list<ExecutionPath *> &c
} }
// bailout used variables in '; FOREACH ( .. ) { .. }' // bailout used variables in '; FOREACH ( .. ) { .. }'
else if (Token::Match(tok->previous(), "[;{}] %var% (")) else if (tok->str() != "if" && Token::Match(tok->previous(), "[;{}] %var% ("))
{ {
// goto { // goto {
const Token *tok2 = tok->tokAt(2); const Token *tok2 = tok->next()->link();
if (tok2 && tok2->str() == "(")
tok2 = tok2->link();
if (tok2 && tok2->str() == ")") if (tok2 && tok2->str() == ")")
tok2 = tok2->next();
if (tok2 && tok2->str() == "{")
{ {
// goto "}" tok2 = tok2->next();
tok2 = tok2->link(); if (tok2 && tok2->str() == "{")
// bail out all variables used in "{ .. }"
for (; tok && tok != tok2; tok = tok->next())
{ {
if (tok->varId()) // goto "}"
ExecutionPath::bailOutVar(checks, tok->varId()); tok2 = tok2->link();
// bail out all variables used in "{ .. }"
for (; tok && tok != tok2; tok = tok->next())
{
if (tok->varId())
ExecutionPath::bailOutVar(checks, tok->varId());
}
} }
} }
} }

View File

@ -1382,6 +1382,15 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: s\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: s\n", errout.str());
checkUninitVar("void a()\n"
"{\n"
" struct S *s1;\n"
" struct S *s2;\n"
" FOREACH(s1) { }\n"
" s2->x = 0;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: s2\n", errout.str());
// #1533 // #1533
checkUninitVar("char a()\n" checkUninitVar("char a()\n"
"{\n" "{\n"