From c67893753823bb3ccad37f95e638b84776526a41 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Wed, 20 Aug 2014 14:57:00 +0200 Subject: [PATCH] Fixed more false positives of #6056: - Implemented nextArgument() for usages before < and > are linked - slightly optimized nextArgument() --- lib/token.cpp | 21 ++++++++++++++++++--- lib/token.h | 10 +++++++++- lib/tokenize.cpp | 4 ++-- test/testtokenize.cpp | 6 +++++- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/lib/token.cpp b/lib/token.cpp index 06ba08388..0932116bc 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -719,9 +719,7 @@ Token* Token::nextArgument() const for (const Token* tok = this; tok; tok = tok->next()) { if (tok->str() == ",") return tok->next(); - else if (tok->str() == "(" || tok->str() == "{" || tok->str() == "[") - tok = tok->link(); - else if (tok->str() == "<" && tok->link()) + else if (tok->link() && (tok->str() == "(" || tok->str() == "{" || tok->str() == "[" || tok->str() == "<")) tok = tok->link(); else if (tok->str() == ")" || tok->str() == ";") return 0; @@ -729,6 +727,23 @@ Token* Token::nextArgument() const return 0; } +Token* Token::nextArgumentBeforeCreateLinks2() const +{ + for (const Token* tok = this; tok; tok = tok->next()) { + if (tok->str() == ",") + return tok->next(); + else if (tok->link() && (tok->str() == "(" || tok->str() == "{" || tok->str() == "[")) + tok = tok->link(); + else if (tok->str() == "<") { + const Token* temp = tok->findClosingBracket(); + if (temp) + tok = temp; + } else if (tok->str() == ")" || tok->str() == ";") + return 0; + } + return 0; +} + const Token * Token::findClosingBracket() const { const Token *closing = nullptr; diff --git a/lib/token.h b/lib/token.h index 242a10fa8..648ee1f34 100644 --- a/lib/token.h +++ b/lib/token.h @@ -618,10 +618,18 @@ public: /** * @return the first token of the next argument. Does only work on argument - * lists. Returns 0, if there is no next argument + * lists. Requires that Tokenizer::createLinks2() has been called before. + * Returns 0, if there is no next argument. */ Token* nextArgument() const; + /** + * @return the first token of the next argument. Does only work on argument + * lists. Should be used only before Tokenizer::createLinks2() was called. + * Returns 0, if there is no next argument. + */ + Token* nextArgumentBeforeCreateLinks2() const; + /** * Returns the closing bracket of opening '<'. Should only be used if link() * is unavailable. diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 604750efe..83747bd6e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2590,8 +2590,8 @@ void Tokenizer::setVarId() if (!executableScope.top()) { // Detecting initializations with () in non-executable scope is hard and often impossible to be done safely. Thus, only treat code as a variable that definitly is one. decl = false; - for (; tok3; tok3 = tok3->nextArgument()) { - if (tok3->isLiteral() || (tok3->isName() && (variableId.find(tok3->str()) != variableId.end())) || tok3->isOp() || (tok3->next()->isOp() && !Token::Match(tok3->next(), "*|&")) || notstart.find(tok3->str()) != notstart.end()) { + for (; tok3; tok3 = tok3->nextArgumentBeforeCreateLinks2()) { + if (tok3->isLiteral() || (tok3->isName() && (variableId.find(tok3->str()) != variableId.end())) || tok3->isOp() || (tok3->next()->isOp() && !Token::Match(tok3->next(), "*|&|<")) || notstart.find(tok3->str()) != notstart.end()) { decl = true; break; } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ef47be692..5f3b66b5d 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -4642,6 +4642,8 @@ private: " int method_with_internal(const B &, int);\n" " void Set(BAR);\n" " FOO Set(BAR);\n" + " int method_with_class(B b);\n" + " bool function(std::map & m);\n" "};"; ASSERT_EQUALS("\n\n##file 0\n" "1: class Fred {\n" @@ -4653,7 +4655,9 @@ private: "7: int method_with_internal ( const B & , int ) ;\n" "8: void Set ( BAR ) ;\n" "9: FOO Set ( BAR ) ;\n" - "10: } ;\n", tokenizeDebugListing(code1, false, "test.cpp")); + "10: int method_with_class ( B < B > b@3 ) ;\n" + "11: bool function ( std :: map < int , int , MYless > & m@4 ) ;\n" + "12: } ;\n", tokenizeDebugListing(code1, false, "test.cpp")); const char code2[] = "int i;\n" "SomeType someVar1(i, i);\n"