From 752e9d0fb734877e75b1708ebed01a4bb077a596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 9 Jan 2014 21:44:29 +0100 Subject: [PATCH] Tokenizer::varId: Fixed wrong varid for shadow types with same names as class members --- lib/tokenize.cpp | 24 +++++++++++++++--------- test/testtokenize.cpp | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d0a52f7b2..022ae2395 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2330,19 +2330,25 @@ static void setVarIdClassDeclaration(Token * const startToken, // Update the variable ids.. // Parse each function.. -static void setVarIdClassFunction(Token * const startToken, +static void setVarIdClassFunction(const std::string &classname, + Token * const startToken, const Token * const endToken, const std::map &varlist, std::map > *structMembers, unsigned int *_varId) { for (Token *tok2 = startToken; tok2 && tok2 != endToken; tok2 = tok2->next()) { - if (tok2->varId() == 0 && (tok2->previous()->str() != "." || tok2->strAt(-2) == "this")) { - const std::map::const_iterator it = varlist.find(tok2->str()); - if (it != varlist.end()) { - tok2->varId(it->second); - setVarIdStructMembers(&tok2, structMembers, _varId); - } + if (tok2->varId() != 0 || !tok2->isName()) + continue; + if (Token::Match(tok2->tokAt(-2), ("!!"+classname+" :: ").c_str())) + continue; + if (Token::Match(tok2->tokAt(-2), "!!this . ")) + continue; + + const std::map::const_iterator it = varlist.find(tok2->str()); + if (it != varlist.end()) { + tok2->varId(it->second); + setVarIdStructMembers(&tok2, structMembers, _varId); } } } @@ -2594,7 +2600,7 @@ void Tokenizer::setVarId() if (Token::Match(tok2, ") const|volatile| {")) { while (tok2->str() != "{") tok2 = tok2->next(); - setVarIdClassFunction(tok2, tok2->link(), varlist, &structMembers, &_varId); + setVarIdClassFunction(classname, tok2, tok2->link(), varlist, &structMembers, &_varId); } // constructor with initializer list @@ -2607,7 +2613,7 @@ void Tokenizer::setVarId() tok3 = tok3->linkAt(3); } if (Token::simpleMatch(tok3, ") {")) { - setVarIdClassFunction(tok2, tok3->next()->link(), varlist, &structMembers, &_varId); + setVarIdClassFunction(classname, tok2, tok3->next()->link(), varlist, &structMembers, &_varId); } } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 33e19fdca..445361ece 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -282,6 +282,7 @@ private: TEST_CASE(varid_in_class11); // #4277 - anonymous union TEST_CASE(varid_in_class12); // #4637 - method TEST_CASE(varid_in_class13); // #4637 - method + TEST_CASE(varid_in_class14); TEST_CASE(varid_initList); TEST_CASE(varid_operator); TEST_CASE(varid_throw); @@ -4451,6 +4452,24 @@ private: tokenizeDebugListing(code2, false, "test.cpp")); } + void varid_in_class14() { + const char code[] = "class Tokenizer { TokenList list; };\n" + "\n" + "void Tokenizer::f() {\n" + " std::list x;\n" // <- not member variable + " list.do_something();\n" // <- member variable + " Tokenizer::list.do_something();\n" // <- redundant scope info + "}\n"; + ASSERT_EQUALS("\n\n##file 0\n" + "1: class Tokenizer { TokenList list@1 ; } ;\n" + "2:\n" + "3: void Tokenizer :: f ( ) {\n" + "4: std :: list < int > x@2 ;\n" + "5: list@1 . do_something ( ) ;\n" + "6: Tokenizer :: list@1 . do_something ( ) ;\n" + "7: }\n", tokenizeDebugListing(code, false, "test.cpp")); + } + void varid_initList() { const char code1[] = "class A {\n" " A() : x(0) {}\n"