From 09189b81e66c095ba5216149aaa75596dfd270fc Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:22:07 +0100 Subject: [PATCH] Fix #12338 "Analysis failed (lambda not recognized)" with trailing type in lambda parameter (#5869) --- lib/tokenlist.cpp | 9 ++++++++ test/testsymboldatabase.cpp | 45 +++++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 4f482d6f177..eeaac111892 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1373,6 +1373,15 @@ const Token* findLambdaEndTokenWithoutAST(const Token* tok) { tok = tok->link()->next(); if (Token::simpleMatch(tok, "(") && tok->link()) tok = tok->link()->next(); + if (Token::simpleMatch(tok, ".")) { // trailing return type + tok = tok->next(); + while (Token::Match(tok, "%type%|%name%|::|&|&&|*|<|(")) { + if (tok->link()) + tok = tok->link()->next(); + else + tok = tok->next(); + } + } if (!(Token::simpleMatch(tok, "{") && tok->link())) return nullptr; return tok->link()->next(); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index b59ed1fbfb7..e68d4eaee93 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -2814,15 +2814,42 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(3, func->argCount()); } - void functionArgs20() { // #11769 - const char code[] = "void f(void *(*g)(void *) = [](void *p) { return p; }) {}"; - GET_SYMBOL_DB(code); - ASSERT(db != nullptr); - const Scope *scope = db->functionScopes.front(); - const Function *func = scope->function; - ASSERT_EQUALS(1, func->argCount()); - const Variable* arg = func->getArgumentVar(0); - TODO_ASSERT(arg->hasDefault()); + void functionArgs20() { + { + const char code[] = "void f(void *(*g)(void *) = [](void *p) { return p; }) {}"; // #11769 + GET_SYMBOL_DB(code); + ASSERT(db != nullptr); + const Scope *scope = db->functionScopes.front(); + const Function *func = scope->function; + ASSERT_EQUALS(1, func->argCount()); + const Variable* arg = func->getArgumentVar(0); + TODO_ASSERT(arg->hasDefault()); + } + { + const char code[] = "void f() { auto g = [&](const std::function& h = [](int i) -> int { return i; }) {}; }"; // #12338 + GET_SYMBOL_DB(code); + ASSERT(db != nullptr); + ASSERT_EQUALS(3, db->scopeList.size()); + ASSERT_EQUALS(Scope::ScopeType::eLambda, db->scopeList.back().type); + } + { + const char code[] = "void f() {\n" + " auto g = [&](const std::function&(const std::vector&)>& h = [](const std::vector& v) -> const std::vector& { return v; }) {};\n" + "}\n"; + GET_SYMBOL_DB(code); + ASSERT(db != nullptr); + ASSERT_EQUALS(3, db->scopeList.size()); + ASSERT_EQUALS(Scope::ScopeType::eLambda, db->scopeList.back().type); + } + { + const char code[] = "void f() {\n" + " auto g = [&](const std::function& h = [](int i) -> decltype(0) { return i; }) {};\n" + "}\n"; + GET_SYMBOL_DB(code); + ASSERT(db != nullptr); + ASSERT_EQUALS(3, db->scopeList.size()); + ASSERT_EQUALS(Scope::ScopeType::eLambda, db->scopeList.back().type); + } } void functionArgs21() {