diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index d23bb5a0e..f5f2729d6 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -620,8 +620,6 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const break; } } - if (i->isArray() && i->isClass()) // Array of class/struct members. Initialized by ctor. - variables.write(i->varId()); if (i->isArray() && Token::Match(i->nameToken(), "%var% [ %var% ]")) // Array index variable read. variables.read(i->nameToken()->tokAt(2)->varId()); @@ -708,7 +706,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const } } - else if (Token::Match(tok, "return|throw")) { + else if (Token::Match(tok, "return|throw %var%")) { for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) { if (tok2->varId()) variables.readAll(tok2->varId()); @@ -840,12 +838,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const } } - else if (Token::Match(tok, "& %var%")) { - if (tok->previous()->isName() || tok->previous()->isNumber()) { // bitop - variables.read(tok->next()->varId()); - } else // addressof - variables.use(tok->next()->varId()); // use = read + write - } else if (Token::Match(tok, ">> %var%")) + else if (Token::Match(tok, ">>|& %var%")) variables.use(tok->next()->varId()); // use = read + write else if (Token::Match(tok, "%var% >>|&") && Token::Match(tok->previous(), "[{};:]")) variables.read(tok->varId()); @@ -872,8 +865,8 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const else if (Token::Match(tok, "%var% .")) variables.use(tok->varId()); // use = read + write - else if (tok->isExtendedOp() && - Token::Match(tok->next(), "%var%") && !Token::Match(tok->next(), "true|false|new") && tok->strAt(2) != "=") + else if ((Token::Match(tok, "[(=&!]") || tok->isExtendedOp()) && + (Token::Match(tok->next(), "%var%") && !Token::Match(tok->next(), "true|false|new")) && tok->strAt(2) != "=") variables.readAll(tok->next()->varId()); else if (Token::Match(tok, "%var%") && (tok->next()->str() == ")" || tok->next()->isExtendedOp())) @@ -1001,9 +994,9 @@ void CheckUnusedVar::checkStructMemberUsage() if (Token::Match(tok, "struct|union %type% {")) { structname.clear(); - if (tok->strAt(-1) == "extern") + if (Token::simpleMatch(tok->previous(), "extern")) continue; - if ((!tok->previous() || tok->previous()->str() == ";") && Token::Match(tok->linkAt(2), ("} ; " + tok->strAt(1) + " %var% ;").c_str())) + if ((!tok->previous() || Token::simpleMatch(tok->previous(), ";")) && Token::Match(tok->linkAt(2), ("} ; " + tok->strAt(1) + " %var% ;").c_str())) continue; structname = tok->strAt(1); diff --git a/lib/checkunusedvar.h b/lib/checkunusedvar.h index eabca9e0c..833713590 100644 --- a/lib/checkunusedvar.h +++ b/lib/checkunusedvar.h @@ -70,7 +70,6 @@ public: /** @brief %Check that all struct members are used */ void checkStructMemberUsage(); -private: // Error messages.. void unusedStructMemberError(const Token *tok, const std::string &structname, const std::string &varname); void unusedVariableError(const Token *tok, const std::string &varname); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 4c44d07f7..92127c2f6 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2299,8 +2299,6 @@ bool Tokenizer::tokenize(std::istream &code, if (!preprocessorCondition) { setVarId(); - createLinks2(); - // Change initialisation of variable to assignment simplifyInitVar(); } @@ -2816,7 +2814,7 @@ void Tokenizer::setVarId() if (Token::Match(tok, "( %type% *|& %var% [),]") && !tok->next()->isStandardType()) { if (!Token::Match(tok->previous(), "%type%")) continue; - if (Token::Match(tok->previous(), "return|if|while")) + if (tok->previous() && tok->previous()->str() == "return") continue; if (tok->link() && !Token::Match(tok->link()->next(), "const| {") && (!tok->link()->next() || tok->link()->next()->str() != ":")) @@ -2867,7 +2865,7 @@ void Tokenizer::setVarId() if (tok->str() == "unsigned") tok = tok->next(); - if (Token::Match(tok, "using namespace %type% ;")) { + if (Token::Match(tok, "using namespace| %type% ;")) { tok = tok->next(); continue; } @@ -3298,62 +3296,6 @@ bool Tokenizer::createLinks() return true; } -void Tokenizer::createLinks2() -{ - std::stack type; - std::stack links; - for (Token *token = _tokens; token; token = token->next()) { - if (token->link()) { - if (Token::Match(token, "{|[|(")) - type.push(token); - else if (Token::Match(token, "}|]|)")) { - while (type.top()->str() == "<") - type.pop(); - type.pop(); - } else - token->link(0); - } - - else if (token->str() == ";") - while (!links.empty()) - links.pop(); - else if (token->str() == "<" && token->previous() && token->previous()->isName() && !token->previous()->varId()) { - type.push(token); - links.push(token); - } else if (token->str() == ">" || token->str() == ">>") { - if (links.empty()) // < and > don't match. - continue; - if (token->next() && !token->next()->isName() && !Token::Match(token->next(), ">|&|*|::|,")) - continue; - - // Check type of open link - if (type.empty() || type.top()->str() != "<" || (token->str() == ">>" && type.size() < 2)) { - if (!links.empty()) - links.pop(); - continue; - } - const Token* top = type.top(); - type.pop(); - if (token->str() == ">>" && type.top()->str() != "<") { - type.push(top); - if (!links.empty()) - links.pop(); - continue; - } - - if (token->str() == ">>") { // C++11 right angle bracket - if (links.size() < 2) - continue; - token->str(">"); - token->insertToken(">"); - } - - Token::createMutualLinks(links.top(), token); - links.pop(); - } - } -} - void Tokenizer::simplifySizeof() { for (Token *tok = _tokens; tok; tok = tok->next()) { @@ -8127,16 +8069,17 @@ bool Tokenizer::validate() const const Token *lastTok = 0; for (const Token *tok = tokens(); tok; tok = tok->next()) { lastTok = tok; - if (Token::Match(tok, "[{([]") || (tok->str() == "<" && tok->link())) { + if (Token::Match(tok, "[{([]")) { if (tok->link() == 0) { cppcheckError(tok); return false; } linktok.push(tok); + continue; } - else if (Token::Match(tok, "[})]]") || (tok->str() == ">" && tok->link())) { + else if (Token::Match(tok, "[})]]")) { if (tok->link() == 0) { cppcheckError(tok); return false; @@ -8158,9 +8101,10 @@ bool Tokenizer::validate() const } linktok.pop(); + continue; } - else if (tok->link() != 0) { + if (tok->link() != 0) { cppcheckError(tok); return false; } diff --git a/lib/tokenize.h b/lib/tokenize.h index ceeb1355a..8727f8a66 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -583,11 +583,6 @@ public: */ bool createLinks(); - /** - * Setup links between < and >. - */ - void createLinks2(); - /** Syntax error */ void syntaxError(const Token *tok); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ef70f6a08..09ec7506f 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -206,7 +206,6 @@ private: TEST_CASE(varid40); // ticket #3279 TEST_CASE(varid41); // ticket #3340 (varid for union type) TEST_CASE(varid42); // ticket #3316 (varid for array) - TEST_CASE(varid43); TEST_CASE(varid44); TEST_CASE(varidFunctionCall1); TEST_CASE(varidFunctionCall2); @@ -224,6 +223,7 @@ private: TEST_CASE(varid_operator); TEST_CASE(varid_throw); TEST_CASE(varid_unknown_macro); // #2638 - unknown macro is not type + TEST_CASE(varid_using); // ticket #3648 TEST_CASE(varidclass1); TEST_CASE(varidclass2); @@ -3249,13 +3249,6 @@ private: tokenizeDebugListing(code)); } - void varid43() { - const std::string code("int main(int flag) { if(a & flag) { return 1; } }"); - ASSERT_EQUALS("\n\n##file 0\n" - "1: int main ( int flag@1 ) { if ( a & flag@1 ) { return 1 ; } }\n", - tokenizeDebugListing(code)); - } - void varid44() { const std::string code("class A:public B,public C,public D {};"); ASSERT_EQUALS("\n\n##file 0\n" @@ -3635,6 +3628,14 @@ private: ASSERT_EQUALS(expected, tokenizeDebugListing(code)); } + void varid_using() { + // #3648 + const char code[] = "using std::size_t;"; + const char expected[] = "\n\n##file 0\n" + "1: using long ;\n"; + ASSERT_EQUALS(expected, tokenizeDebugListing(code)); + } + void varidclass1() { const std::string actual = tokenizeDebugListing( "class Fred\n" @@ -5052,33 +5053,6 @@ private: ASSERT_EQUALS(true, tok->linkAt(8) == tok->tokAt(9)); ASSERT_EQUALS(true, tok->linkAt(9) == tok->tokAt(8)); } - - { - const char code[] = "bool foo(C a, bar>& f, int b) {\n" - " return(af);\n" - "}"; - errout.str(""); - Settings settings; - Tokenizer tokenizer(&settings, this); - std::istringstream istr(code); - tokenizer.tokenize(istr, "test.cpp"); - const Token *tok = tokenizer.tokens(); - // template< - ASSERT_EQUALS((long long)tok->tokAt(6), (long long)tok->linkAt(4)); - ASSERT_EQUALS((long long)tok->tokAt(4), (long long)tok->linkAt(6)); - - // bar< - ASSERT_EQUALS((long long)tok->tokAt(17), (long long)tok->linkAt(10)); - ASSERT_EQUALS((long long)tok->tokAt(10), (long long)tok->linkAt(17)); - - // x< - ASSERT_EQUALS((long long)tok->tokAt(16), (long long)tok->linkAt(14)); - ASSERT_EQUALS((long long)tok->tokAt(14), (long long)tok->linkAt(16)); - - // af - ASSERT_EQUALS(0, (long long)tok->linkAt(28)); - ASSERT_EQUALS(0, (long long)tok->linkAt(32)); - } } void removeExceptionSpecification1() { @@ -5344,7 +5318,8 @@ private: void cpp0xtemplate2() { // tokenize ">>" into "> >" const char *code = "list> ints;\n"; - ASSERT_EQUALS("list < list < int > > ints ;", tokenizeAndStringify(code)); + TODO_ASSERT_EQUALS("list < list < int > > ints ;", + "list < list < int >> ints ;", tokenizeAndStringify(code)); } void cpp0xtemplate3() {