Detect lambda with template argument (#5202)
This commit is contained in:
parent
0a72cd3b72
commit
4f71bbe986
|
@ -2977,9 +2977,12 @@ T* findLambdaEndTokenGeneric(T* first)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!maybeLambda(first->previous()))
|
if (!maybeLambda(first->previous()))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!Token::Match(first->link(), "] (|{"))
|
if (!Token::Match(first->link(), "] (|{|<"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (first->astOperand1() != first->link()->next())
|
const Token* roundOrCurly = first->link()->next();
|
||||||
|
if (roundOrCurly->link() && roundOrCurly->str() == "<")
|
||||||
|
roundOrCurly = roundOrCurly->link()->next();
|
||||||
|
if (first->astOperand1() != roundOrCurly)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
T * tok = first;
|
T * tok = first;
|
||||||
|
|
||||||
|
|
|
@ -909,7 +909,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
|
||||||
}
|
}
|
||||||
compileBinOp(tok, state, compileScope);
|
compileBinOp(tok, state, compileScope);
|
||||||
} else if (tok->str() == "[") {
|
} else if (tok->str() == "[") {
|
||||||
if (state.cpp && isPrefixUnary(tok, state.cpp) && Token::Match(tok->link(), "] (|{")) { // Lambda
|
if (state.cpp && isPrefixUnary(tok, state.cpp) && Token::Match(tok->link(), "] (|{|<")) { // Lambda
|
||||||
// What we do here:
|
// What we do here:
|
||||||
// - Nest the round bracket under the square bracket.
|
// - Nest the round bracket under the square bracket.
|
||||||
// - Nest what follows the lambda (if anything) with the lambda opening [
|
// - Nest what follows the lambda (if anything) with the lambda opening [
|
||||||
|
@ -926,8 +926,10 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::simpleMatch(squareBracket->link(), "] (")) {
|
const bool hasTemplateArg = Token::simpleMatch(squareBracket->link(), "] <") &&
|
||||||
Token* const roundBracket = squareBracket->link()->next();
|
Token::simpleMatch(squareBracket->link()->next()->link(), "> (");
|
||||||
|
if (Token::simpleMatch(squareBracket->link(), "] (") || hasTemplateArg) {
|
||||||
|
Token* const roundBracket = hasTemplateArg ? squareBracket->link()->next()->link()->next() : squareBracket->link()->next();
|
||||||
Token* curlyBracket = roundBracket->link()->next();
|
Token* curlyBracket = roundBracket->link()->next();
|
||||||
while (Token::Match(curlyBracket, "mutable|const|constexpr|consteval"))
|
while (Token::Match(curlyBracket, "mutable|const|constexpr|consteval"))
|
||||||
curlyBracket = curlyBracket->next();
|
curlyBracket = curlyBracket->next();
|
||||||
|
|
|
@ -472,6 +472,7 @@ private:
|
||||||
TEST_CASE(lambda2); // #7473
|
TEST_CASE(lambda2); // #7473
|
||||||
TEST_CASE(lambda3);
|
TEST_CASE(lambda3);
|
||||||
TEST_CASE(lambda4);
|
TEST_CASE(lambda4);
|
||||||
|
TEST_CASE(lambda5);
|
||||||
|
|
||||||
TEST_CASE(circularDependencies); // #6298
|
TEST_CASE(circularDependencies); // #6298
|
||||||
|
|
||||||
|
@ -7775,6 +7776,26 @@ private:
|
||||||
ASSERT_EQUALS(s.type()->classScope, &*scope);
|
ASSERT_EQUALS(s.type()->classScope, &*scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lambda5() { // #11275
|
||||||
|
GET_SYMBOL_DB("int* f() {\n"
|
||||||
|
" auto g = []<typename T>() {\n"
|
||||||
|
" return true;\n"
|
||||||
|
" };\n"
|
||||||
|
" return nullptr;\n"
|
||||||
|
"}\n");
|
||||||
|
|
||||||
|
ASSERT(db && db->scopeList.size() == 3);
|
||||||
|
std::list<Scope>::const_iterator scope = db->scopeList.cbegin();
|
||||||
|
ASSERT_EQUALS(Scope::eGlobal, scope->type);
|
||||||
|
++scope;
|
||||||
|
ASSERT_EQUALS(Scope::eFunction, scope->type);
|
||||||
|
++scope;
|
||||||
|
ASSERT_EQUALS(Scope::eLambda, scope->type);
|
||||||
|
const Token* ret = Token::findsimplematch(tokenizer.tokens(), "return true");
|
||||||
|
ASSERT(ret && ret->scope());
|
||||||
|
ASSERT_EQUALS(ret->scope()->type, Scope::eLambda);
|
||||||
|
}
|
||||||
|
|
||||||
// #6298 "stack overflow in Scope::findFunctionInBase (endless recursion)"
|
// #6298 "stack overflow in Scope::findFunctionInBase (endless recursion)"
|
||||||
void circularDependencies() {
|
void circularDependencies() {
|
||||||
check("template<template<class> class E,class D> class C : E<D> {\n"
|
check("template<template<class> class E,class D> class C : E<D> {\n"
|
||||||
|
|
Loading…
Reference in New Issue