diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 1e1430649..ca40cd815 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -6198,9 +6198,9 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source Token::Match(parent->tokAt(-1), "%var% ="))) { Token *var1Tok = parent->strAt(-2) == ";" ? parent->tokAt(-3) : parent->tokAt(-1); Token *autoTok = nullptr; - if (Token::Match(var1Tok->tokAt(-2), ";|{|}|(|const|constexpr auto")) + if (Token::simpleMatch(var1Tok->tokAt(-1), "auto")) autoTok = var1Tok->previous(); - else if (Token::Match(var1Tok->tokAt(-3), ";|{|}|(|const|constexpr auto *|&|&&")) + else if (Token::Match(var1Tok->tokAt(-2), "auto *|&|&&")) autoTok = var1Tok->tokAt(-2); if (autoTok) { ValueType vt(*vt2); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1646c2029..7e485f859 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4574,7 +4574,7 @@ void Tokenizer::setVarIdPass1() continue; if (tok3->isLiteral() || - (tok3->isName() && variableMap.hasVariable(tok3->str())) || + (tok3->isName() && (variableMap.hasVariable(tok3->str()) || (tok3->strAt(-1) == "(" && Token::simpleMatch(tok3->next(), "(")))) || tok3->isOp() || tok3->str() == "(" || notstart.find(tok3->str()) != notstart.end()) { @@ -4786,7 +4786,11 @@ static Token * matchMemberName(const Member &member, const std::list static Token * matchMemberVarName(const Member &var, const std::list &scopeInfo) { Token *tok = matchMemberName(var, scopeInfo); - return Token::Match(tok, "%name% !!(") ? tok : nullptr; + if (Token::Match(tok, "%name%")) { + if (!tok->next() || tok->strAt(1) != "(" || (tok->tokAt(2) && tok->tokAt(2)->isLiteral())) + return tok; + } + return nullptr; } static Token * matchMemberFunctionName(const Member &func, const std::list &scopeInfo) @@ -4854,7 +4858,7 @@ void Tokenizer::setVarIdPass2() } if (!tok->next()) syntaxError(tok); - if (Token::Match(tok, "%name% (")) + if (Token::Match(tok, "%name% (") && !(tok->tokAt(2) && tok->tokAt(2)->isLiteral())) allMemberFunctions.emplace_back(scope, usingnamespaces, tok1); else allMemberVars.emplace_back(scope, usingnamespaces, tok1); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 554b4d909..1faa936d0 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -5262,7 +5262,7 @@ private: void createSymbolDatabaseFindAllScopes5() { - GET_SYMBOL_DB("class C {\n" + GET_SYMBOL_DB("class C {\n" // #11444 "public:\n" " template\n" " class D;\n" @@ -5282,7 +5282,12 @@ private: ASSERT(db); ASSERT_EQUALS(6, db->scopeList.size()); const Token* const var = Token::findsimplematch(tokenizer.tokens(), "IN ("); - TODO_ASSERT(var && var->variable()); + ASSERT(var && var->variable()); + ASSERT_EQUALS(var->variable()->name(), "IN"); + auto it = db->scopeList.begin(); + std::advance(it, 4); + ASSERT_EQUALS(it->className, "S"); + ASSERT_EQUALS(var->variable()->scope(), &*it); } void createSymbolDatabaseFindAllScopes6() @@ -7686,23 +7691,35 @@ private: } void executableScopeWithUnknownFunction() { - GET_SYMBOL_DB("class Fred {\n" - " void foo(const std::string & a = \"\");\n" - "};\n" - "Fred::foo(const std::string & b) { }"); + { + GET_SYMBOL_DB("class Fred {\n" + " void foo(const std::string & a = \"\");\n" + "};\n" + "Fred::foo(const std::string & b) { }"); - ASSERT(db && db->scopeList.size() == 3); - std::list::const_iterator scope = db->scopeList.cbegin(); - ASSERT_EQUALS(Scope::eGlobal, scope->type); - ++scope; - ASSERT_EQUALS(Scope::eClass, scope->type); - const Scope * class_scope = &*scope; - ++scope; - ASSERT(class_scope->functionList.size() == 1); - ASSERT(class_scope->functionList.cbegin()->hasBody()); - ASSERT(class_scope->functionList.cbegin()->functionScope == &*scope); + ASSERT(db && db->scopeList.size() == 3); + std::list::const_iterator scope = db->scopeList.cbegin(); + ASSERT_EQUALS(Scope::eGlobal, scope->type); + ++scope; + ASSERT_EQUALS(Scope::eClass, scope->type); + const Scope* class_scope = &*scope; + ++scope; + ASSERT(class_scope->functionList.size() == 1); + ASSERT(class_scope->functionList.cbegin()->hasBody()); + ASSERT(class_scope->functionList.cbegin()->functionScope == &*scope); + } + { + GET_SYMBOL_DB("bool f(bool (*g)(int));\n" + "bool f(bool (*g)(int)) { return g(0); }\n"); + + ASSERT(db && db->scopeList.size() == 2); + std::list::const_iterator scope = db->scopeList.cbegin(); + ASSERT_EQUALS(Scope::eGlobal, scope->type); + ASSERT(scope->functionList.size() == 1); + ++scope; + ASSERT_EQUALS(Scope::eFunction, scope->type); + } } - #define typeOf(...) typeOf_(__FILE__, __LINE__, __VA_ARGS__) std::string typeOf_(const char* file, int line, const char code[], const char pattern[], const char filename[] = "test.cpp", const Settings *settings = nullptr) { Tokenizer tokenizer(settings ? settings : &settings2, this); @@ -8375,6 +8392,15 @@ private: ASSERT(tok->variable() && tok->variable()->valueType()); ASSERT_EQUALS("signed int * const &", tok->variable()->valueType()->str()); } + { + GET_SYMBOL_DB("auto a = 1;\n"); + ASSERT_EQUALS("", errout.str()); + + const Token* tok = tokenizer.tokens(); + tok = Token::findsimplematch(tok, "auto"); + ASSERT(tok && tok->valueType()); + ASSERT_EQUALS("signed int", tok->valueType()->str()); + } } void valueTypeThis() { diff --git a/test/testvarid.cpp b/test/testvarid.cpp index 087e2526e..dc076aa7d 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -102,6 +102,7 @@ private: TEST_CASE(varid63); TEST_CASE(varid64); // #9928 - extern const char (*x[256]) TEST_CASE(varid65); // #10936 + TEST_CASE(varid66); TEST_CASE(varid_for_1); TEST_CASE(varid_for_2); TEST_CASE(varid_cpp_keywords_in_c_code); @@ -1195,6 +1196,14 @@ private: } } + void varid66() { + const char code[] = "std::string g();\n" + "const std::string s(g() + \"abc\");\n"; + const char expected[] = "1: std :: string g ( ) ;\n" + "2: const std :: string s@1 ( g ( ) + \"abc\" ) ;\n"; + ASSERT_EQUALS(expected, tokenize(code)); + } + void varid_for_1() { const char code[] = "void foo(int a, int b) {\n" " for (int a=1,b=2;;) {}\n"