diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index f0631d533..fd9a145da 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -19,6 +19,7 @@ //--------------------------------------------------------------------------- #include "symboldatabase.h" +#include "astutils.h" #include "errorlogger.h" #include "platform.h" #include "settings.h" @@ -640,27 +641,21 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() else if (scope->type == Scope::eCatch) scope->checkVariable(tok->tokAt(2), Throw, mSettings); // check for variable declaration and add it to new scope if found tok = scopeStartTok; + } else if (Token::Match(tok, "%var% {")) { + tok = tok->linkAt(1); + } else if (const Token *lambdaEndToken = findLambdaEndToken(tok)) { + const Token *lambdaStartToken = lambdaEndToken->link(); + scopeList.emplace_back(this, tok, scope, Scope::eLambda, lambdaStartToken); + scope->nestedList.push_back(&scopeList.back()); + scope = &scopeList.back(); + tok = lambdaStartToken; } else if (tok->str() == "{") { - if (tok->previous()->varId()) + if (!Token::Match(tok->previous(), "=|,|(|return") && !(tok->strAt(-1) == ")" && Token::Match(tok->linkAt(-1)->previous(), "=|,|(|return"))) { + scopeList.emplace_back(this, tok, scope, Scope::eUnconditional, tok); + scope->nestedList.push_back(&scopeList.back()); + scope = &scopeList.back(); + } else { tok = tok->link(); - else { - const Token* tok2 = tok->previous(); - while (!Token::Match(tok2, ";|}|{|)")) - tok2 = tok2->previous(); - if (tok2->next() != tok && tok2->strAt(1) != ".") - tok2 = nullptr; // No lambda - - if (tok2 && tok2->str() == ")" && tok2->link()->strAt(-1) == "]") { - scopeList.emplace_back(this, tok2->link()->linkAt(-1), scope, Scope::eLambda, tok); - scope->nestedList.push_back(&scopeList.back()); - scope = &scopeList.back(); - } else if (!Token::Match(tok->previous(), "=|,|(|return") && !(tok->strAt(-1) == ")" && Token::Match(tok->linkAt(-1)->previous(), "=|,|(|return"))) { - scopeList.emplace_back(this, tok, scope, Scope::eUnconditional, tok); - scope->nestedList.push_back(&scopeList.back()); - scope = &scopeList.back(); - } else { - tok = tok->link(); - } } } } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index a6a909a14..19910b9fc 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -359,6 +359,7 @@ private: TEST_CASE(lambda); // #5867 TEST_CASE(lambda2); // #7473 + TEST_CASE(lambda3); TEST_CASE(circularDependencies); // #6298 @@ -5835,6 +5836,24 @@ private: ASSERT_EQUALS(Scope::eLambda, scope->type); } } + + + void lambda3() { + GET_SYMBOL_DB("void func() {\n" + " auto f = []() mutable {}\n" + "}"); + + ASSERT(db && db->scopeList.size() == 3); + if (db && db->scopeList.size() == 3) { + std::list::const_iterator scope = db->scopeList.begin(); + ASSERT_EQUALS(Scope::eGlobal, scope->type); + ++scope; + ASSERT_EQUALS(Scope::eFunction, scope->type); + ++scope; + ASSERT_EQUALS(Scope::eLambda, scope->type); + } + } + // #6298 "stack overflow in Scope::findFunctionInBase (endless recursion)" void circularDependencies() { check("template class E,class D> class C : E {\n"