From be8e3dac34092fab438f23494a9d64139ab146be Mon Sep 17 00:00:00 2001 From: chrchr Date: Thu, 11 Jan 2024 10:44:41 +0100 Subject: [PATCH 1/3] Fix #12338 "Analysis failed (lambda not recognized)" with trailing type in lambda parameter --- lib/tokenlist.cpp | 9 +++++++++ test/testsymboldatabase.cpp | 27 ++++++++++++++++++--------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 4f482d6f177..e25cfda1025 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->str() == "<") + tok = tok->link(); + 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..8a7272457a2 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -2814,15 +2814,24 @@ 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); + } } void functionArgs21() { From 8f4b44f142a0835db02fb23648d454aa9b611182 Mon Sep 17 00:00:00 2001 From: chrchr Date: Thu, 11 Jan 2024 10:56:58 +0100 Subject: [PATCH 2/3] Add test --- lib/tokenlist.cpp | 2 +- test/testsymboldatabase.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index e25cfda1025..ed16c1c5eb5 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1377,7 +1377,7 @@ const Token* findLambdaEndTokenWithoutAST(const Token* tok) { tok = tok->next(); while (Token::Match(tok, "%type%|%name%|::|&|&&|*|<")) { if (tok->str() == "<") - tok = tok->link(); + tok = tok->link()->next(); else tok = tok->next(); } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 8a7272457a2..b9a41a5cf85 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -2832,6 +2832,15 @@ class TestSymbolDatabase : public TestFixture { 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); + } } void functionArgs21() { From 963fae77b067b05bb6e529c340a8b5a110355d23 Mon Sep 17 00:00:00 2001 From: chrchr Date: Fri, 12 Jan 2024 11:13:54 +0100 Subject: [PATCH 3/3] decltype --- lib/tokenlist.cpp | 4 ++-- test/testsymboldatabase.cpp | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index ed16c1c5eb5..eeaac111892 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1375,8 +1375,8 @@ const Token* findLambdaEndTokenWithoutAST(const Token* tok) { tok = tok->link()->next(); if (Token::simpleMatch(tok, ".")) { // trailing return type tok = tok->next(); - while (Token::Match(tok, "%type%|%name%|::|&|&&|*|<")) { - if (tok->str() == "<") + while (Token::Match(tok, "%type%|%name%|::|&|&&|*|<|(")) { + if (tok->link()) tok = tok->link()->next(); else tok = tok->next(); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index b9a41a5cf85..e68d4eaee93 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -2841,6 +2841,15 @@ class TestSymbolDatabase : public TestFixture { 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() {