Fix 10588: crash (#3691)
This commit is contained in:
parent
9220c8175d
commit
4af98f21d6
|
@ -1704,6 +1704,11 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
|||
while (Token::Match(tok1, "%type%|*|&") && !endsWith(tok1->str(), ':') && (!isReservedName(tok1->str()) || tok1->str() == "const"))
|
||||
tok1 = tok1->previous();
|
||||
|
||||
// skip over decltype
|
||||
if (Token::simpleMatch(tok1, ")") && tok1->link() &&
|
||||
Token::simpleMatch(tok1->link()->previous(), "decltype ("))
|
||||
tok1 = tok1->link()->tokAt(-2);
|
||||
|
||||
// skip over template
|
||||
if (tok1 && tok1->str() == ">") {
|
||||
if (tok1->link())
|
||||
|
@ -1730,6 +1735,9 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
|||
tok1 = tok1->previous();
|
||||
else if (tok1 && tok1->str() == ">" && tok1->link() && Token::Match(tok1->link()->previous(), "%name%"))
|
||||
tok1 = tok1->link()->tokAt(-2);
|
||||
else if (Token::simpleMatch(tok1, ")") && tok1->link() &&
|
||||
Token::simpleMatch(tok1->link()->previous(), "decltype ("))
|
||||
tok1 = tok1->link()->tokAt(-2);
|
||||
}
|
||||
|
||||
// skip over modifiers and other stuff
|
||||
|
@ -2348,6 +2356,11 @@ const Token *Function::setFlags(const Token *tok1, const Scope *scope)
|
|||
isConstexpr(true);
|
||||
}
|
||||
|
||||
// decltype
|
||||
else if (tok1->str() == ")" && Token::simpleMatch(tok1->link()->previous(), "decltype (")) {
|
||||
tok1 = tok1->link()->previous();
|
||||
}
|
||||
|
||||
// Function template
|
||||
else if (tok1->link() && tok1->str() == ">" && Token::simpleMatch(tok1->link()->previous(), "template <")) {
|
||||
templateDef = tok1->link()->previous();
|
||||
|
|
|
@ -192,6 +192,7 @@ private:
|
|||
TEST_CASE(hasMissingInlineClassFunction);
|
||||
TEST_CASE(hasClassFunction);
|
||||
TEST_CASE(hasClassFunction_trailingReturnType);
|
||||
TEST_CASE(hasClassFunction_decltype_auto);
|
||||
|
||||
TEST_CASE(hasRegularFunctionReturningFunctionPointer);
|
||||
TEST_CASE(hasInlineClassFunctionReturningFunctionPointer);
|
||||
|
@ -1629,6 +1630,28 @@ private:
|
|||
ASSERT(function && function->functionScope == scope && scope->function == function && function->nestedIn == db->findScopeByName("Fred"));
|
||||
}
|
||||
|
||||
void hasClassFunction_decltype_auto()
|
||||
{
|
||||
GET_SYMBOL_DB("struct d { decltype(auto) f() {} };");
|
||||
|
||||
// 3 scopes: Global, Class, and Function
|
||||
ASSERT(db && db->scopeList.size() == 3);
|
||||
|
||||
const Token* const functionToken = Token::findsimplematch(tokenizer.tokens(), "f");
|
||||
|
||||
const Scope* scope = findFunctionScopeByToken(db, functionToken);
|
||||
|
||||
ASSERT(scope && scope->className == "f");
|
||||
|
||||
ASSERT(scope->functionOf && scope->functionOf == db->findScopeByName("d"));
|
||||
|
||||
const Function* function = findFunctionByName("f", &db->scopeList.back());
|
||||
|
||||
ASSERT(function && function->token->str() == "f");
|
||||
ASSERT(function && function->token == functionToken);
|
||||
ASSERT(function && function->hasBody());
|
||||
}
|
||||
|
||||
void hasRegularFunctionReturningFunctionPointer() {
|
||||
GET_SYMBOL_DB("void (*func(int f))(char) { }");
|
||||
|
||||
|
|
|
@ -6185,6 +6185,18 @@ private:
|
|||
" } while (last > 0);\n"
|
||||
"}\n";
|
||||
valueOfTok(code, "last");
|
||||
|
||||
code = "struct a {\n"
|
||||
" void clear();\n"
|
||||
" int b();\n"
|
||||
"};\n"
|
||||
"struct d {\n"
|
||||
" void c(int);\n"
|
||||
" decltype(auto) f() { c(0 != e.b()); }\n"
|
||||
" a e;\n"
|
||||
"};\n"
|
||||
"void d::c(int) { e.clear(); }\n";
|
||||
valueOfTok(code, "e");
|
||||
}
|
||||
|
||||
void valueFlowHang() {
|
||||
|
|
Loading…
Reference in New Issue