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:
parent
de4d44ae2f
commit
ad2f71338c
|
@ -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 {};'
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue