Fix issue 9525: Syntax Error: AST broken, 'if' doesn't have two operands inside lambda (#2433)

* Fix issue 9525: Syntax Error: AST broken, 'if' doesn't have two operands inside lambda

* Fix incorrect matchers
This commit is contained in:
Paul Fultz II 2019-12-10 14:21:07 -06:00 committed by Daniel Marjamäki
parent de4d44ae2f
commit ad2f71338c
2 changed files with 87 additions and 5 deletions

View File

@ -516,6 +516,47 @@ static bool iscast(const Token *tok)
return false;
}
static const Token* findTypeEnd(const Token* tok)
{
while(Token::Match(tok, "%name%|.|::|<|(|template|decltype|sizeof")) {
if (Token::Match(tok, "(|<"))
tok = tok->link();
if (!tok)
return nullptr;
tok = tok->next();
}
return tok;
}
static const Token * findLambdaEndScope(const Token *tok)
{
if (!Token::simpleMatch(tok, "["))
return nullptr;
tok = tok->link();
if (!Token::Match(tok, "] (|{"))
return nullptr;
tok = tok->linkAt(1);
if (Token::simpleMatch(tok, "}"))
return tok;
if (Token::simpleMatch(tok, ") {"))
return tok->linkAt(1);
if (!Token::simpleMatch(tok, ")"))
return nullptr;
tok = tok->next();
while(Token::Match(tok, "mutable|constexpr|constval|noexcept|.")) {
if (Token::simpleMatch(tok, "noexcept ("))
tok = tok->linkAt(1);
if (Token::simpleMatch(tok, ".")) {
tok = findTypeEnd(tok);
break;
}
tok = tok->next();
}
if (Token::simpleMatch(tok, "{"))
return tok->link();
return nullptr;
}
// int(1), int*(2), ..
static Token * findCppTypeInitPar(Token *tok)
{
@ -567,7 +608,7 @@ static bool iscpp11init_impl(const Token * const tok)
nameToken = nameToken->link()->previous();
const Token *endtok = nullptr;
if (Token::Match(nameToken, "%name% { !!["))
if (Token::Match(nameToken, "%name%|return {") && (!Token::simpleMatch(nameToken->tokAt(2), "[") || findLambdaEndScope(nameToken->tokAt(2))))
endtok = nameToken->linkAt(1);
else if (Token::Match(nameToken,"%name% <") && Token::simpleMatch(nameToken->linkAt(1),"> {"))
endtok = nameToken->linkAt(1)->linkAt(1);
@ -584,8 +625,9 @@ static bool iscpp11init_impl(const Token * const tok)
for (const Token *tok2 = nameToken->next(); tok2 != endtok; tok2 = tok2->next()) {
if (tok2->str() == ";")
return false;
if (tok2->str() == "[" && Token::simpleMatch(tok2->link(), "] (") && Token::simpleMatch(tok2->link()->linkAt(1), ") {"))
tok2 = tok2->link()->linkAt(1)->linkAt(1);
const Token * lambdaEnd = findLambdaEndScope(tok2);
if (lambdaEnd)
tok2 = lambdaEnd;
}
}
// There is no initialisation for example here: 'class Fred {};'

View File

@ -7818,18 +7818,30 @@ private:
// 8628
ASSERT_EQUALS("f{([( switchx( 1case y++", testAst("f([](){switch(x){case 1:{++y;}}});"));
ASSERT_EQUALS("{return ab=",
ASSERT_EQUALS("{([{return ab=",
testAst("return {\n"
" [=]() {\n"
" a = b;\n"
" }\n"
"};\n"));
ASSERT_EQUALS("{return ab=",
ASSERT_EQUALS("{[{return ab=",
testAst("return {\n"
" [=] {\n"
" a = b;\n"
" }\n"
"};\n"));
ASSERT_EQUALS("{([{return ab=",
testAst("return {\n"
" [=]() -> int {\n"
" a=b;\n"
" }\n"
"}"));
ASSERT_EQUALS("{([{return ab=",
testAst("return {\n"
" [=]() mutable -> int {\n"
" a=b;\n"
" }\n"
"}"));
// daca@home hang
ASSERT_EQUALS("a{([= 0return b{([= fori0=i10!=i++;;(",
@ -8112,6 +8124,34 @@ private:
" auto b = [this, a] {};\n"
" }\n"
"};\n"))
// #9525
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"
" template <class b> a(b) {}\n"
"};\n"
"auto c() -> a {\n"
" return {[] {\n"
" if (0) {}\n"
" }};\n"
"}\n"))
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"
" template <class b> a(b) {}\n"
"};\n"
"auto c() -> a {\n"
" return {[]() -> int {\n"
" if (0) {}\n"
" return 0;\n"
" }};\n"
"}\n"))
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"
" template <class b> a(b) {}\n"
"};\n"
"auto c() -> a {\n"
" return {[]() mutable -> int {\n"
" if (0) {}\n"
" return 0;\n"
" }};\n"
"}\n"))
}
void checkIfCppCast() {
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"