Tokenizer::setVarId: Better handling of class declarations when variable usage comes before variable declaration

This commit is contained in:
Daniel Marjamäki 2011-03-19 09:04:03 +01:00
parent afc7fd82ed
commit 45a3828da7
3 changed files with 50 additions and 6 deletions

View File

@ -3580,11 +3580,36 @@ void Tokenizer::setVarId()
// Variable declaration found => Set variable ids // Variable declaration found => Set variable ids
if (Token::Match(tok2, "[,();[=]") && !varname.empty()) if (Token::Match(tok2, "[,();[=]") && !varname.empty())
{ {
// Are we in a class declaration?
// Then start at the start of the class declaration..
while (NULL != (tok2 = tok2->previous()))
{
if (tok2->str() == "}" || tok2->str() == ")")
tok2 = tok2->link();
else if (tok2->str() == "(")
break;
else if (tok2->str() == "{")
{
while (NULL != (tok2 = tok2->previous()))
{
if (Token::Match(tok2, "[,;{})]"))
break;
if (Token::Match(tok2, "class|struct"))
break;
}
break;
}
}
// Start token
if (!Token::Match(tok2, "class|struct"))
tok2 = tok;
++_varId; ++_varId;
int indentlevel = 0; int indentlevel = 0;
int parlevel = 0; int parlevel = 0;
bool funcDeclaration = false; bool funcDeclaration = false;
for (tok2 = tok->next(); tok2; tok2 = tok2->next()) while (NULL != (tok2 = tok2->next()))
{ {
const char c = tok2->str()[0]; const char c = tok2->str()[0];
if (c == varname[0]) if (c == varname[0])

View File

@ -4235,8 +4235,7 @@ private:
"private:\n" "private:\n"
" char *s;\n" " char *s;\n"
"};\n"); "};\n");
TODO_ASSERT_EQUALS("publicAllocation", ASSERT_EQUALS("[test.cpp:7]: (warning) Possible leak in public function. The pointer 's' is not deallocated before it is allocated.\n", errout.str());
"", errout.str());
} }
void func2() void func2()

View File

@ -193,6 +193,7 @@ private:
TEST_CASE(varidclass7); TEST_CASE(varidclass7);
TEST_CASE(varidclass8); TEST_CASE(varidclass8);
TEST_CASE(varidclass9); TEST_CASE(varidclass9);
TEST_CASE(varidclass10); // variable declaration below usage
TEST_CASE(file1); TEST_CASE(file1);
TEST_CASE(file2); TEST_CASE(file2);
@ -3090,7 +3091,7 @@ private:
"10:\n" "10:\n"
"11: void Bar :: f ( )\n" "11: void Bar :: f ( )\n"
"12: {\n" "12: {\n"
"13: foo@2 . x = x@3 ;\n" // TODO: it would be even better if the ". x" was ". x@4" instead "13: foo@2 . x@4 = x@3 ;\n"
"14: }\n"); "14: }\n");
ASSERT_EQUALS(expected, actual); ASSERT_EQUALS(expected, actual);
} }
@ -3261,7 +3262,7 @@ private:
"8:\n" "8:\n"
"9: void A :: f ( )\n" "9: void A :: f ( )\n"
"10: {\n" "10: {\n"
"11: i = 0 ;\n" "11: i@1 = 0 ;\n"
"12: }\n"); "12: }\n");
ASSERT_EQUALS(expected, actual); ASSERT_EQUALS(expected, actual);
@ -3381,7 +3382,7 @@ private:
"1: class Fred {\n" "1: class Fred {\n"
"2: public:\n" "2: public:\n"
"3: void foo ( int d@1 ) {\n" "3: void foo ( int d@1 ) {\n"
"4: int i@2 ; i@2 = bar ( x * d@1 ) ;\n" "4: int i@2 ; i@2 = bar ( x@3 * d@1 ) ;\n"
"5: }\n" "5: }\n"
"6: int x@3 ;\n" "6: int x@3 ;\n"
"7: }\n"); "7: }\n");
@ -3415,6 +3416,25 @@ private:
ASSERT_EQUALS(expected, tokenizeDebugListing(code)); ASSERT_EQUALS(expected, tokenizeDebugListing(code));
} }
void varidclass10()
{
const std::string code("class A {\n"
" void f() {\n"
" a = 3;\n"
" }\n"
" int a;\n"
"};\n;");
const std::string expected("\n\n##file 0\n"
"1: class A {\n"
"2: void f ( ) {\n"
"3: a@1 = 3 ;\n"
"4: }\n"
"5: int a@1 ;\n"
"6: } ;\n");
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
}
void file1() void file1()
{ {