Skip to content

Commit 4f71bbe

Browse files
Detect lambda with template argument (#5202)
1 parent 0a72cd3 commit 4f71bbe

3 files changed

Lines changed: 31 additions & 5 deletions

File tree

lib/astutils.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2977,9 +2977,12 @@ T* findLambdaEndTokenGeneric(T* first)
29772977
return nullptr;
29782978
if (!maybeLambda(first->previous()))
29792979
return nullptr;
2980-
if (!Token::Match(first->link(), "] (|{"))
2980+
if (!Token::Match(first->link(), "] (|{|<"))
29812981
return nullptr;
2982-
if (first->astOperand1() != first->link()->next())
2982+
const Token* roundOrCurly = first->link()->next();
2983+
if (roundOrCurly->link() && roundOrCurly->str() == "<")
2984+
roundOrCurly = roundOrCurly->link()->next();
2985+
if (first->astOperand1() != roundOrCurly)
29832986
return nullptr;
29842987
T * tok = first;
29852988

lib/tokenlist.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
909909
}
910910
compileBinOp(tok, state, compileScope);
911911
} else if (tok->str() == "[") {
912-
if (state.cpp && isPrefixUnary(tok, state.cpp) && Token::Match(tok->link(), "] (|{")) { // Lambda
912+
if (state.cpp && isPrefixUnary(tok, state.cpp) && Token::Match(tok->link(), "] (|{|<")) { // Lambda
913913
// What we do here:
914914
// - Nest the round bracket under the square bracket.
915915
// - Nest what follows the lambda (if anything) with the lambda opening [
@@ -926,8 +926,10 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
926926
}
927927
}
928928

929-
if (Token::simpleMatch(squareBracket->link(), "] (")) {
930-
Token* const roundBracket = squareBracket->link()->next();
929+
const bool hasTemplateArg = Token::simpleMatch(squareBracket->link(), "] <") &&
930+
Token::simpleMatch(squareBracket->link()->next()->link(), "> (");
931+
if (Token::simpleMatch(squareBracket->link(), "] (") || hasTemplateArg) {
932+
Token* const roundBracket = hasTemplateArg ? squareBracket->link()->next()->link()->next() : squareBracket->link()->next();
931933
Token* curlyBracket = roundBracket->link()->next();
932934
while (Token::Match(curlyBracket, "mutable|const|constexpr|consteval"))
933935
curlyBracket = curlyBracket->next();

test/testsymboldatabase.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ class TestSymbolDatabase : public TestFixture {
472472
TEST_CASE(lambda2); // #7473
473473
TEST_CASE(lambda3);
474474
TEST_CASE(lambda4);
475+
TEST_CASE(lambda5);
475476

476477
TEST_CASE(circularDependencies); // #6298
477478

@@ -7775,6 +7776,26 @@ class TestSymbolDatabase : public TestFixture {
77757776
ASSERT_EQUALS(s.type()->classScope, &*scope);
77767777
}
77777778

7779+
void lambda5() { // #11275
7780+
GET_SYMBOL_DB("int* f() {\n"
7781+
" auto g = []<typename T>() {\n"
7782+
" return true;\n"
7783+
" };\n"
7784+
" return nullptr;\n"
7785+
"}\n");
7786+
7787+
ASSERT(db && db->scopeList.size() == 3);
7788+
std::list<Scope>::const_iterator scope = db->scopeList.cbegin();
7789+
ASSERT_EQUALS(Scope::eGlobal, scope->type);
7790+
++scope;
7791+
ASSERT_EQUALS(Scope::eFunction, scope->type);
7792+
++scope;
7793+
ASSERT_EQUALS(Scope::eLambda, scope->type);
7794+
const Token* ret = Token::findsimplematch(tokenizer.tokens(), "return true");
7795+
ASSERT(ret && ret->scope());
7796+
ASSERT_EQUALS(ret->scope()->type, Scope::eLambda);
7797+
}
7798+
77787799
// #6298 "stack overflow in Scope::findFunctionInBase (endless recursion)"
77797800
void circularDependencies() {
77807801
check("template<template<class> class E,class D> class C : E<D> {\n"

0 commit comments

Comments
 (0)