Fixed #1273 (scope of variable limited not detected in latest versions)

This commit is contained in:
Daniel Marjamäki 2010-01-21 18:50:56 +01:00
parent 9f0b9551cf
commit 2e707974d0
2 changed files with 28 additions and 9 deletions

View File

@ -457,10 +457,11 @@ void CheckOther::lookupVar(const Token *tok1, const char varname[])
tok = tok->next(); tok = tok->next();
// Check if the variable is used in this indentlevel.. // Check if the variable is used in this indentlevel..
bool used = false, used1 = false; bool used1 = false; // used in one sub-scope -> reducable
bool used2 = false; // used in more sub-scopes -> not reducable
int indentlevel = 0; int indentlevel = 0;
int parlevel = 0; int parlevel = 0;
bool for_or_while = false; bool for_or_while = false; // is sub-scope a "for/while/etc". anything that is not "if"
while (tok) while (tok)
{ {
if (tok->str() == "{") if (tok->str() == "{")
@ -475,10 +476,10 @@ void CheckOther::lookupVar(const Token *tok1, const char varname[])
--indentlevel; --indentlevel;
if (indentlevel == 0) if (indentlevel == 0)
{ {
if (for_or_while && used) if (for_or_while && used2)
return; return;
used1 |= used; used2 |= used1;
used = false; used1 = false;
} }
} }
@ -500,9 +501,13 @@ void CheckOther::lookupVar(const Token *tok1, const char varname[])
else if (tok->str() == varname) else if (tok->str() == varname)
{ {
if (indentlevel == 0 || used1) if (indentlevel == 0)
return;
used1 = true;
if (for_or_while && !Token::simpleMatch(tok->next(), "="))
used2 = true;
if (used1 && used2)
return; return;
used = true;
} }
else if (indentlevel == 0) else if (indentlevel == 0)
@ -511,7 +516,7 @@ void CheckOther::lookupVar(const Token *tok1, const char varname[])
// If %unknown% is anything except if, we assume // If %unknown% is anything except if, we assume
// that it is a for or while loop or a macro hiding either one // that it is a for or while loop or a macro hiding either one
if (Token::simpleMatch(tok->next(), "(") && if (Token::simpleMatch(tok->next(), "(") &&
Token::simpleMatch(tok->next()->link()->next(), "{")) Token::simpleMatch(tok->next()->link(), ") {"))
{ {
if (tok->str() != "if") if (tok->str() != "if")
for_or_while = true; for_or_while = true;
@ -530,7 +535,7 @@ void CheckOther::lookupVar(const Token *tok1, const char varname[])
// Warning if this variable: // Warning if this variable:
// * not used in this indentlevel // * not used in this indentlevel
// * used in lower indentlevel // * used in lower indentlevel
if (!used && used1) if (used1 || used2)
variableScopeError(tok1, varname); variableScopeError(tok1, varname);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -60,6 +60,7 @@ private:
TEST_CASE(varScope5); TEST_CASE(varScope5);
TEST_CASE(varScope6); TEST_CASE(varScope6);
TEST_CASE(varScope7); TEST_CASE(varScope7);
TEST_CASE(varScope8);
TEST_CASE(nullpointer1); TEST_CASE(nullpointer1);
TEST_CASE(nullpointer2); TEST_CASE(nullpointer2);
@ -601,6 +602,19 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void varScope8()
{
varScope("void test() {\n"
" float edgeResistance=1;\n"
" std::vector<int> edges;\n"
" BOOST_FOREACH(int edge, edges) {\n"
" edgeResistance = (edge+1) / 2.0;\n"
" }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2]: (style) The scope of the variable edgeResistance can be reduced\n", errout.str());
}
void checkNullPointer(const char code[]) void checkNullPointer(const char code[])
{ {
// Tokenize.. // Tokenize..