SymbolDatabase: Properly detect lambdas with return type (#7473)

This commit is contained in:
PKEuS 2016-05-04 14:10:09 +02:00
parent f0fb7a8245
commit 6c3f0a7bb8
2 changed files with 44 additions and 13 deletions

View File

@ -793,16 +793,24 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
} else if (tok->str() == "{") {
if (tok->previous()->varId())
tok = tok->link();
else if (tok->strAt(-1) == ")" && tok->linkAt(-1)->strAt(-1) == "]") {
scopeList.push_back(Scope(this, tok->linkAt(-1)->linkAt(-1), scope, Scope::eLambda, tok));
scope->nestedList.push_back(&scopeList.back());
scope = &scopeList.back();
} else if (!Token::Match(tok->previous(), "=|,|(|return") && !(tok->strAt(-1) == ")" && Token::Match(tok->linkAt(-1)->previous(), "=|,|(|return"))) {
scopeList.push_back(Scope(this, tok, scope, Scope::eUnconditional, tok));
scope->nestedList.push_back(&scopeList.back());
scope = &scopeList.back();
} else {
tok = tok->link();
else {
const Token* tok2 = tok->previous();
while (!Token::Match(tok2, ";|}|{|)"))
tok2 = tok2->previous();
if (tok2->next() != tok && tok2->strAt(1) != ".")
tok2 = nullptr; // No lambda
if (tok2 && tok2->str() == ")" && tok2->link()->strAt(-1) == "]") {
scopeList.push_back(Scope(this, tok2->link()->linkAt(-1), scope, Scope::eLambda, tok));
scope->nestedList.push_back(&scopeList.back());
scope = &scopeList.back();
} else if (!Token::Match(tok->previous(), "=|,|(|return") && !(tok->strAt(-1) == ")" && Token::Match(tok->linkAt(-1)->previous(), "=|,|(|return"))) {
scopeList.push_back(Scope(this, tok, scope, Scope::eUnconditional, tok));
scope->nestedList.push_back(&scopeList.back());
scope = &scopeList.back();
} else {
tok = tok->link();
}
}
}
}

View File

@ -271,10 +271,12 @@ private:
TEST_CASE(varTypesFloating); // known floating
TEST_CASE(varTypesOther); // (un)known
TEST_CASE(functionPrototype); // ticket #5867
TEST_CASE(functionPrototype); // #5867
TEST_CASE(lambda); // ticket #5867
TEST_CASE(circularDependencies); // 6298
TEST_CASE(lambda); // #5867
TEST_CASE(lambda2); // #7473
TEST_CASE(circularDependencies); // #6298
TEST_CASE(executableScopeWithUnknownFunction);
@ -3105,6 +3107,27 @@ private:
ASSERT_EQUALS(Scope::eLambda, scope->type);
}
}
void lambda2() {
GET_SYMBOL_DB("void func() {\n"
" float y = 0.0f;\n"
" auto lambda = [&]() -> bool\n"
" {\n"
" float x = 1.0f;\n"
" }\n"
" lambda();\n"
"}");
ASSERT(db && db->scopeList.size() == 3);
if (db && db->scopeList.size() == 3) {
std::list<Scope>::const_iterator scope = db->scopeList.begin();
ASSERT_EQUALS(Scope::eGlobal, scope->type);
++scope;
ASSERT_EQUALS(Scope::eFunction, scope->type);
++scope;
ASSERT_EQUALS(Scope::eLambda, scope->type);
}
}
// #6298 "stack overflow in Scope::findFunctionInBase (endless recursion)"
void circularDependencies() {
check("template<template<class> class E,class D> class C : E<D> {\n"