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;
|
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), ..
|
// int(1), int*(2), ..
|
||||||
static Token * findCppTypeInitPar(Token *tok)
|
static Token * findCppTypeInitPar(Token *tok)
|
||||||
{
|
{
|
||||||
|
@ -567,7 +608,7 @@ static bool iscpp11init_impl(const Token * const tok)
|
||||||
nameToken = nameToken->link()->previous();
|
nameToken = nameToken->link()->previous();
|
||||||
|
|
||||||
const Token *endtok = nullptr;
|
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);
|
endtok = nameToken->linkAt(1);
|
||||||
else if (Token::Match(nameToken,"%name% <") && Token::simpleMatch(nameToken->linkAt(1),"> {"))
|
else if (Token::Match(nameToken,"%name% <") && Token::simpleMatch(nameToken->linkAt(1),"> {"))
|
||||||
endtok = nameToken->linkAt(1)->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()) {
|
for (const Token *tok2 = nameToken->next(); tok2 != endtok; tok2 = tok2->next()) {
|
||||||
if (tok2->str() == ";")
|
if (tok2->str() == ";")
|
||||||
return false;
|
return false;
|
||||||
if (tok2->str() == "[" && Token::simpleMatch(tok2->link(), "] (") && Token::simpleMatch(tok2->link()->linkAt(1), ") {"))
|
const Token * lambdaEnd = findLambdaEndScope(tok2);
|
||||||
tok2 = tok2->link()->linkAt(1)->linkAt(1);
|
if (lambdaEnd)
|
||||||
|
tok2 = lambdaEnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// There is no initialisation for example here: 'class Fred {};'
|
// There is no initialisation for example here: 'class Fred {};'
|
||||||
|
|
|
@ -7818,18 +7818,30 @@ private:
|
||||||
// 8628
|
// 8628
|
||||||
ASSERT_EQUALS("f{([( switchx( 1case y++", testAst("f([](){switch(x){case 1:{++y;}}});"));
|
ASSERT_EQUALS("f{([( switchx( 1case y++", testAst("f([](){switch(x){case 1:{++y;}}});"));
|
||||||
|
|
||||||
ASSERT_EQUALS("{return ab=",
|
ASSERT_EQUALS("{([{return ab=",
|
||||||
testAst("return {\n"
|
testAst("return {\n"
|
||||||
" [=]() {\n"
|
" [=]() {\n"
|
||||||
" a = b;\n"
|
" a = b;\n"
|
||||||
" }\n"
|
" }\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"
|
testAst("return {\n"
|
||||||
" [=]() -> int {\n"
|
" [=]() -> int {\n"
|
||||||
" a=b;\n"
|
" a=b;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}"));
|
"}"));
|
||||||
|
ASSERT_EQUALS("{([{return ab=",
|
||||||
|
testAst("return {\n"
|
||||||
|
" [=]() mutable -> int {\n"
|
||||||
|
" a=b;\n"
|
||||||
|
" }\n"
|
||||||
|
"}"));
|
||||||
|
|
||||||
// daca@home hang
|
// daca@home hang
|
||||||
ASSERT_EQUALS("a{([= 0return b{([= fori0=i10!=i++;;(",
|
ASSERT_EQUALS("a{([= 0return b{([= fori0=i10!=i++;;(",
|
||||||
|
@ -8112,6 +8124,34 @@ private:
|
||||||
" auto b = [this, a] {};\n"
|
" auto b = [this, a] {};\n"
|
||||||
" }\n"
|
" }\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() {
|
void checkIfCppCast() {
|
||||||
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"
|
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"
|
||||||
|
|
Loading…
Reference in New Issue