Skip to content

Commit

Permalink
Fix #12552 FP: syntaxError on valid code (#6198)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github authored Apr 3, 2024
1 parent d98efaf commit d5e58ff
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
3 changes: 2 additions & 1 deletion lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8641,7 +8641,8 @@ void Tokenizer::findGarbageCode() const
syntaxError(tok);
if (Token::Match(tok, "==|!=|<=|>= %comp%") && tok->strAt(-1) != "operator")
syntaxError(tok, tok->str() + " " + tok->strAt(1));
if (Token::simpleMatch(tok, "::") && (!Token::Match(tok->next(), "%name%|*|~") || (tok->next()->isKeyword() && tok->strAt(1) != "operator")))
if (Token::simpleMatch(tok, "::") && (!Token::Match(tok->next(), "%name%|*|~") ||
(tok->next()->isKeyword() && !Token::Match(tok->next(), "new|delete|operator"))))
syntaxError(tok);
if (Token::Match(tok, "& %comp%|&&|%oror%|&|%or%") && tok->strAt(1) != ">")
syntaxError(tok);
Expand Down
10 changes: 9 additions & 1 deletion lib/tokenlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ static void compileTerm(Token *&tok, AST_state& state)
tok = tok->next();
} while (Token::Match(tok, "%name%|%str%"));
} else if (tok->isName()) {
if (Token::Match(tok, "return|case") || (state.cpp && (tok->str() == "throw" || Token::simpleMatch(tok->tokAt(-1), ":: new")))) {
if (Token::Match(tok, "return|case") || (state.cpp && (tok->str() == "throw"))) {
if (tok->str() == "case")
state.inCase = true;
const bool tokIsReturn = tok->str() == "return";
Expand Down Expand Up @@ -1160,6 +1160,10 @@ static void compilePrecedence3(Token *&tok, AST_state& state)
compilePrecedence2(tok, state);
}
compileUnaryOp(newtok, state, nullptr);
if (Token::simpleMatch(newtok->previous(), ":: new")) {
newtok->previous()->astOperand1(newtok);
state.op.pop();
}
if (innertype && Token::simpleMatch(tok, ") ,"))
tok = tok->next();
} else if (state.cpp && Token::Match(tok, "delete %name%|*|&|::|(|[")) {
Expand All @@ -1169,6 +1173,10 @@ static void compilePrecedence3(Token *&tok, AST_state& state)
tok = tok->link()->next();
compilePrecedence3(tok, state);
compileUnaryOp(tok2, state, nullptr);
if (Token::simpleMatch(tok2->previous(), ":: delete")) {
tok2->previous()->astOperand1(tok2);
state.op.pop();
}
}
// TODO: Handle sizeof
else break;
Expand Down
5 changes: 5 additions & 0 deletions test/testtokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6251,6 +6251,8 @@ class TestTokenizer : public TestFixture {
ASSERT_EQUALS("pint5[{new=", testAst("p = new int* [5]{};"));
ASSERT_EQUALS("pint5[0{new=", testAst("p = new int* [5]{ 0 };"));
ASSERT_EQUALS("sSint(new::(new=", testAst("s = new S(::new int());")); // #12502
ASSERT_EQUALS("sS(new::=", testAst("s = ::new (ptr) S();")); // #12552
ASSERT_EQUALS("pdelete::return", testAst("return ::delete p;"));

// placement new
ASSERT_EQUALS("X12,3,(new ab,c,", testAst("new (a,b,c) X(1,2,3);"));
Expand Down Expand Up @@ -7083,6 +7085,9 @@ class TestTokenizer : public TestFixture {
"There is an unknown macro here somewhere. Configuration is required. If MACRO is a macro then please configure it.");

ASSERT_THROW(tokenizeAndStringify("{ for (()()) }"), InternalError); // #11643

ASSERT_NO_THROW(tokenizeAndStringify("S* g = ::new(ptr) S();")); // #12552
ASSERT_NO_THROW(tokenizeAndStringify("void f(int* p) { return ::delete p; }"));
}


Expand Down

0 comments on commit d5e58ff

Please sign in to comment.