* Fix #11719 Handle lambdas in global scope * Capture list
This commit is contained in:
parent
1999bc68bf
commit
518b6a27ab
|
@ -141,6 +141,16 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
return endInitList.top().second == scope;
|
||||
};
|
||||
|
||||
auto addLambda = [this, &scope](const Token* tok, const Token* lambdaEndToken) -> const Token* {
|
||||
const Token* lambdaStartToken = lambdaEndToken->link();
|
||||
const Token* argStart = lambdaStartToken->astParent();
|
||||
const Token* funcStart = Token::simpleMatch(argStart, "[") ? argStart : argStart->astParent();
|
||||
const Function* function = addGlobalFunction(scope, tok, argStart, funcStart);
|
||||
if (!function)
|
||||
mTokenizer.syntaxError(tok);
|
||||
return lambdaStartToken;
|
||||
};
|
||||
|
||||
// Store current access in each scope (depends on evaluation progress)
|
||||
std::map<const Scope*, AccessControl> access;
|
||||
|
||||
|
@ -674,6 +684,8 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
tok = declEnd;
|
||||
continue;
|
||||
}
|
||||
} else if (const Token *lambdaEndToken = findLambdaEndToken(tok)) {
|
||||
tok = addLambda(tok, lambdaEndToken);
|
||||
}
|
||||
} else if (scope->isExecutable()) {
|
||||
if (tok->isKeyword() && Token::Match(tok, "else|try|do {")) {
|
||||
|
@ -712,13 +724,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
|||
endInitList.emplace(tok->next()->link(), scope);
|
||||
tok = tok->next();
|
||||
} else if (const Token *lambdaEndToken = findLambdaEndToken(tok)) {
|
||||
const Token *lambdaStartToken = lambdaEndToken->link();
|
||||
const Token * argStart = lambdaStartToken->astParent();
|
||||
const Token * funcStart = Token::simpleMatch(argStart, "[") ? argStart : argStart->astParent();
|
||||
const Function * function = addGlobalFunction(scope, tok, argStart, funcStart);
|
||||
if (!function)
|
||||
mTokenizer.syntaxError(tok);
|
||||
tok = lambdaStartToken;
|
||||
tok = addLambda(tok, lambdaEndToken);
|
||||
} else if (tok->str() == "{") {
|
||||
if (inInitList()) {
|
||||
endInitList.emplace(tok->link(), scope);
|
||||
|
|
|
@ -467,6 +467,7 @@ private:
|
|||
TEST_CASE(lambda); // #5867
|
||||
TEST_CASE(lambda2); // #7473
|
||||
TEST_CASE(lambda3);
|
||||
TEST_CASE(lambda4);
|
||||
|
||||
TEST_CASE(circularDependencies); // #6298
|
||||
|
||||
|
@ -7686,7 +7687,6 @@ private:
|
|||
ASSERT_EQUALS(Scope::eLambda, scope->type);
|
||||
}
|
||||
|
||||
|
||||
void lambda3() {
|
||||
GET_SYMBOL_DB("void func() {\n"
|
||||
" auto f = []() mutable {}\n"
|
||||
|
@ -7701,6 +7701,28 @@ private:
|
|||
ASSERT_EQUALS(Scope::eLambda, scope->type);
|
||||
}
|
||||
|
||||
void lambda4() { // #11719
|
||||
GET_SYMBOL_DB("struct S { int* p; };\n"
|
||||
"auto g = []() {\n"
|
||||
" S s;\n"
|
||||
" s.p = new int;\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::eStruct, scope->type);
|
||||
++scope;
|
||||
ASSERT_EQUALS(Scope::eLambda, scope->type);
|
||||
ASSERT_EQUALS(1, scope->varlist.size());
|
||||
const Variable& s = scope->varlist.front();
|
||||
ASSERT_EQUALS(s.name(), "s");
|
||||
ASSERT(s.type());
|
||||
--scope;
|
||||
ASSERT_EQUALS(s.type()->classScope, &*scope);
|
||||
}
|
||||
|
||||
// #6298 "stack overflow in Scope::findFunctionInBase (endless recursion)"
|
||||
void circularDependencies() {
|
||||
check("template<template<class> class E,class D> class C : E<D> {\n"
|
||||
|
|
Loading…
Reference in New Issue