diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 3955b4c67..66a7196d8 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2948,9 +2948,9 @@ static bool setVarIdParseDeclaration(const Token **tok, const std::map >& structMembers, - unsigned int *varId) +void Tokenizer::setVarIdStructMembers(Token **tok1, + std::map >& structMembers, + unsigned int *varId) { Token *tok = *tok1; @@ -2982,6 +2982,12 @@ static void setVarIdStructMembers(Token **tok1, } while (Token::Match(tok->next(), ")| . %name% !!(")) { + // Don't set varid for trailing return type + if (tok->strAt(1) == ")" && tok->linkAt(1)->previous()->isName() && + isFunctionHead(tok->linkAt(1), "{|;")) { + tok = tok->tokAt(3); + continue; + } const unsigned int struct_varid = tok->varId(); tok = tok->tokAt(2); if (struct_varid == 0) @@ -3086,12 +3092,12 @@ void Tokenizer::setVarIdClassDeclaration(const Token * const startToken, // Update the variable ids.. // Parse each function.. -static void setVarIdClassFunction(const std::string &classname, - Token * const startToken, - const Token * const endToken, - const std::map &varlist, - std::map >& structMembers, - unsigned int *varId_) +void Tokenizer::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->isName()) diff --git a/lib/tokenize.h b/lib/tokenize.h index a0129689f..6be6c2c5c 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -761,6 +761,16 @@ private: const unsigned int scopeStartVarId, std::map >& structMembers); + void setVarIdStructMembers(Token **tok1, + std::map >& structMembers, + unsigned int *varId); + + void setVarIdClassFunction(const std::string &classname, + Token * const startToken, + const Token * const endToken, + const std::map &varlist, + std::map >& structMembers, + unsigned int *varId_); /** * Simplify e.g. 'return(strncat(temp,"a",1));' into diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 90b64260e..378377060 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -4234,8 +4234,7 @@ private: " using namespace bar::baz;\n" " auto func(int arg) -> bar::quux {}\n" "}"); - // bar on line 3 should not have a varid - TODO_ASSERT_EQUALS(2, 3, db->mVariableList.size()); + ASSERT_EQUALS(2, db->mVariableList.size()); } void createSymbolDatabaseFindAllScopes1() { diff --git a/test/testvarid.cpp b/test/testvarid.cpp index 8c63fc2a4..82d7588c3 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -162,6 +162,8 @@ private: TEST_CASE(varid_arrayinit); // #7579 TEST_CASE(varid_lambda_arg); TEST_CASE(varid_lambda_mutable); + TEST_CASE(varid_trailing_return1); // #8889 + TEST_CASE(varid_trailing_return2); // #9066 TEST_CASE(varidclass1); TEST_CASE(varidclass2); @@ -2514,6 +2516,34 @@ private: ASSERT_EQUALS(exp1, tokenize(code1)); } + void varid_trailing_return1() { // #8889 + const char code1[] = "struct Fred {\n" + " auto foo(const Fred & other) -> Fred &;\n" + " auto bar(const Fred & other) -> Fred & {\n" + " return *this;\n" + " }\n" + "};\n" + "auto Fred::foo(const Fred & other) -> Fred & {\n" + " return *this;\n" + "}"; + const char exp1[] = "1: struct Fred {\n" + "2: auto foo ( const Fred & other@1 ) . Fred & ;\n" + "3: auto bar ( const Fred & other@2 ) . Fred & {\n" + "4: return * this ;\n" + "5: }\n" + "6: } ;\n" + "7: auto Fred :: foo ( const Fred & other@3 ) . Fred & {\n" + "8: return * this ;\n" + "9: }\n"; + ASSERT_EQUALS(exp1, tokenize(code1)); + } + + void varid_trailing_return2() { // #9066 + const char code1[] = "auto func(int arg) -> bar::quux {}"; + const char exp1[] = "1: auto func ( int arg@1 ) . bar :: quux { }\n"; + ASSERT_EQUALS(exp1, tokenize(code1)); + } + void varidclass1() { const std::string actual = tokenize( "class Fred\n"