* 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;
|
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)
|
// Store current access in each scope (depends on evaluation progress)
|
||||||
std::map<const Scope*, AccessControl> access;
|
std::map<const Scope*, AccessControl> access;
|
||||||
|
|
||||||
|
@ -674,6 +684,8 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
||||||
tok = declEnd;
|
tok = declEnd;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
} else if (const Token *lambdaEndToken = findLambdaEndToken(tok)) {
|
||||||
|
tok = addLambda(tok, lambdaEndToken);
|
||||||
}
|
}
|
||||||
} else if (scope->isExecutable()) {
|
} else if (scope->isExecutable()) {
|
||||||
if (tok->isKeyword() && Token::Match(tok, "else|try|do {")) {
|
if (tok->isKeyword() && Token::Match(tok, "else|try|do {")) {
|
||||||
|
@ -712,13 +724,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
||||||
endInitList.emplace(tok->next()->link(), scope);
|
endInitList.emplace(tok->next()->link(), scope);
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
} else if (const Token *lambdaEndToken = findLambdaEndToken(tok)) {
|
} else if (const Token *lambdaEndToken = findLambdaEndToken(tok)) {
|
||||||
const Token *lambdaStartToken = lambdaEndToken->link();
|
tok = addLambda(tok, lambdaEndToken);
|
||||||
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;
|
|
||||||
} else if (tok->str() == "{") {
|
} else if (tok->str() == "{") {
|
||||||
if (inInitList()) {
|
if (inInitList()) {
|
||||||
endInitList.emplace(tok->link(), scope);
|
endInitList.emplace(tok->link(), scope);
|
||||||
|
|
|
@ -467,6 +467,7 @@ private:
|
||||||
TEST_CASE(lambda); // #5867
|
TEST_CASE(lambda); // #5867
|
||||||
TEST_CASE(lambda2); // #7473
|
TEST_CASE(lambda2); // #7473
|
||||||
TEST_CASE(lambda3);
|
TEST_CASE(lambda3);
|
||||||
|
TEST_CASE(lambda4);
|
||||||
|
|
||||||
TEST_CASE(circularDependencies); // #6298
|
TEST_CASE(circularDependencies); // #6298
|
||||||
|
|
||||||
|
@ -7686,7 +7687,6 @@ private:
|
||||||
ASSERT_EQUALS(Scope::eLambda, scope->type);
|
ASSERT_EQUALS(Scope::eLambda, scope->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void lambda3() {
|
void lambda3() {
|
||||||
GET_SYMBOL_DB("void func() {\n"
|
GET_SYMBOL_DB("void func() {\n"
|
||||||
" auto f = []() mutable {}\n"
|
" auto f = []() mutable {}\n"
|
||||||
|
@ -7701,6 +7701,28 @@ private:
|
||||||
ASSERT_EQUALS(Scope::eLambda, scope->type);
|
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)"
|
// #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