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"))
|
while (Token::Match(tok1, "%type%|*|&") && !endsWith(tok1->str(), ':') && (!isReservedName(tok1->str()) || tok1->str() == "const"))
|
||||||
tok1 = tok1->previous();
|
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
|
// skip over template
|
||||||
if (tok1 && tok1->str() == ">") {
|
if (tok1 && tok1->str() == ">") {
|
||||||
if (tok1->link())
|
if (tok1->link())
|
||||||
|
@ -1730,6 +1735,9 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
||||||
tok1 = tok1->previous();
|
tok1 = tok1->previous();
|
||||||
else if (tok1 && tok1->str() == ">" && tok1->link() && Token::Match(tok1->link()->previous(), "%name%"))
|
else if (tok1 && tok1->str() == ">" && tok1->link() && Token::Match(tok1->link()->previous(), "%name%"))
|
||||||
tok1 = tok1->link()->tokAt(-2);
|
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
|
// skip over modifiers and other stuff
|
||||||
|
@ -2348,6 +2356,11 @@ const Token *Function::setFlags(const Token *tok1, const Scope *scope)
|
||||||
isConstexpr(true);
|
isConstexpr(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// decltype
|
||||||
|
else if (tok1->str() == ")" && Token::simpleMatch(tok1->link()->previous(), "decltype (")) {
|
||||||
|
tok1 = tok1->link()->previous();
|
||||||
|
}
|
||||||
|
|
||||||
// Function template
|
// Function template
|
||||||
else if (tok1->link() && tok1->str() == ">" && Token::simpleMatch(tok1->link()->previous(), "template <")) {
|
else if (tok1->link() && tok1->str() == ">" && Token::simpleMatch(tok1->link()->previous(), "template <")) {
|
||||||
templateDef = tok1->link()->previous();
|
templateDef = tok1->link()->previous();
|
||||||
|
|
|
@ -192,6 +192,7 @@ private:
|
||||||
TEST_CASE(hasMissingInlineClassFunction);
|
TEST_CASE(hasMissingInlineClassFunction);
|
||||||
TEST_CASE(hasClassFunction);
|
TEST_CASE(hasClassFunction);
|
||||||
TEST_CASE(hasClassFunction_trailingReturnType);
|
TEST_CASE(hasClassFunction_trailingReturnType);
|
||||||
|
TEST_CASE(hasClassFunction_decltype_auto);
|
||||||
|
|
||||||
TEST_CASE(hasRegularFunctionReturningFunctionPointer);
|
TEST_CASE(hasRegularFunctionReturningFunctionPointer);
|
||||||
TEST_CASE(hasInlineClassFunctionReturningFunctionPointer);
|
TEST_CASE(hasInlineClassFunctionReturningFunctionPointer);
|
||||||
|
@ -1629,6 +1630,28 @@ private:
|
||||||
ASSERT(function && function->functionScope == scope && scope->function == function && function->nestedIn == db->findScopeByName("Fred"));
|
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() {
|
void hasRegularFunctionReturningFunctionPointer() {
|
||||||
GET_SYMBOL_DB("void (*func(int f))(char) { }");
|
GET_SYMBOL_DB("void (*func(int f))(char) { }");
|
||||||
|
|
||||||
|
|
|
@ -6185,6 +6185,18 @@ private:
|
||||||
" } while (last > 0);\n"
|
" } while (last > 0);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
valueOfTok(code, "last");
|
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() {
|
void valueFlowHang() {
|
||||||
|
|
Loading…
Reference in New Issue