Fix issue 9535: Syntax Error: AST broken, 'if' doesn't have two operands. (#2450)

This commit is contained in:
Paul Fultz II 2019-12-16 05:17:01 -06:00 committed by Daniel Marjamäki
parent 890d11ccf2
commit ad352daa08
2 changed files with 16 additions and 6 deletions

View File

@ -516,9 +516,9 @@ static bool iscast(const Token *tok)
return false; return false;
} }
static const Token* findTypeEnd(const Token* tok) static Token* findTypeEnd(Token* tok)
{ {
while (Token::Match(tok, "%name%|.|::|<|(|template|decltype|sizeof")) { while (Token::Match(tok, "%name%|.|::|*|&|<|(|template|decltype|sizeof")) {
if (Token::Match(tok, "(|<")) if (Token::Match(tok, "(|<"))
tok = tok->link(); tok = tok->link();
if (!tok) if (!tok)
@ -528,6 +528,11 @@ static const Token* findTypeEnd(const Token* tok)
return tok; return tok;
} }
static const Token* findTypeEnd(const Token* tok)
{
return findTypeEnd(const_cast<Token*>(tok));
}
static const Token * findLambdaEndScope(const Token *tok) static const Token * findLambdaEndScope(const Token *tok)
{ {
if (!Token::simpleMatch(tok, "[")) if (!Token::simpleMatch(tok, "["))
@ -867,10 +872,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
if (Token::Match(curlyBracket, "mutable|const")) if (Token::Match(curlyBracket, "mutable|const"))
curlyBracket = curlyBracket->next(); curlyBracket = curlyBracket->next();
if (curlyBracket && curlyBracket->originalName() == "->") { if (curlyBracket && curlyBracket->originalName() == "->") {
while (Token::Match(curlyBracket, "%name%|.|::|&|*")) curlyBracket = findTypeEnd(curlyBracket->next());
curlyBracket = curlyBracket->next();
if (curlyBracket && curlyBracket->str() == "<" && curlyBracket->link())
curlyBracket = curlyBracket->link()->next();
} }
if (curlyBracket && curlyBracket->str() == "{") { if (curlyBracket && curlyBracket->str() == "{") {
squareBracket->astOperand1(roundBracket); squareBracket->astOperand1(roundBracket);

View File

@ -7811,6 +7811,7 @@ private:
ASSERT_EQUALS("{([(return 0return", testAst("return []() -> int { return 0; }();")); ASSERT_EQUALS("{([(return 0return", testAst("return []() -> int { return 0; }();"));
ASSERT_EQUALS("{([(return 0return", testAst("return [something]() -> int { return 0; }();")); ASSERT_EQUALS("{([(return 0return", testAst("return [something]() -> int { return 0; }();"));
ASSERT_EQUALS("{([cd,(return 0return", testAst("return [](int a, int b) -> int { return 0; }(c, d);")); ASSERT_EQUALS("{([cd,(return 0return", testAst("return [](int a, int b) -> int { return 0; }(c, d);"));
ASSERT_EQUALS("{([return", testAst("return []() -> decltype(0) {};"));
ASSERT_EQUALS("x{([=", testAst("x = [&]()->std::string const & {};")); ASSERT_EQUALS("x{([=", testAst("x = [&]()->std::string const & {};"));
ASSERT_EQUALS("f{([=", testAst("f = []() -> foo* {};")); ASSERT_EQUALS("f{([=", testAst("f = []() -> foo* {};"));
ASSERT_EQUALS("f{([=", testAst("f = [](void) mutable -> foo* {};")); ASSERT_EQUALS("f{([=", testAst("f = [](void) mutable -> foo* {};"));
@ -8159,6 +8160,13 @@ private:
" return 0;\n" " return 0;\n"
" }};\n" " }};\n"
"}\n")) "}\n"))
// #0535
ASSERT_NO_THROW(tokenizeAndStringify("template <typename, typename> struct a;\n"
"template <typename, typename b> void c() {\n"
" ([]() -> decltype(0) {\n"
" if (a<b, decltype(0)>::d) {}\n"
" });\n"
"}\n"))
} }
void checkIfCppCast() { void checkIfCppCast() {
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n" ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"