Skip to content

Commit d5e58ff

Browse files
Fix #12552 FP: syntaxError on valid code (#6198)
1 parent d98efaf commit d5e58ff

3 files changed

Lines changed: 16 additions & 2 deletions

File tree

lib/tokenize.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8641,7 +8641,8 @@ void Tokenizer::findGarbageCode() const
86418641
syntaxError(tok);
86428642
if (Token::Match(tok, "==|!=|<=|>= %comp%") && tok->strAt(-1) != "operator")
86438643
syntaxError(tok, tok->str() + " " + tok->strAt(1));
8644-
if (Token::simpleMatch(tok, "::") && (!Token::Match(tok->next(), "%name%|*|~") || (tok->next()->isKeyword() && tok->strAt(1) != "operator")))
8644+
if (Token::simpleMatch(tok, "::") && (!Token::Match(tok->next(), "%name%|*|~") ||
8645+
(tok->next()->isKeyword() && !Token::Match(tok->next(), "new|delete|operator"))))
86458646
syntaxError(tok);
86468647
if (Token::Match(tok, "& %comp%|&&|%oror%|&|%or%") && tok->strAt(1) != ">")
86478648
syntaxError(tok);

lib/tokenlist.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ static void compileTerm(Token *&tok, AST_state& state)
749749
tok = tok->next();
750750
} while (Token::Match(tok, "%name%|%str%"));
751751
} else if (tok->isName()) {
752-
if (Token::Match(tok, "return|case") || (state.cpp && (tok->str() == "throw" || Token::simpleMatch(tok->tokAt(-1), ":: new")))) {
752+
if (Token::Match(tok, "return|case") || (state.cpp && (tok->str() == "throw"))) {
753753
if (tok->str() == "case")
754754
state.inCase = true;
755755
const bool tokIsReturn = tok->str() == "return";
@@ -1160,6 +1160,10 @@ static void compilePrecedence3(Token *&tok, AST_state& state)
11601160
compilePrecedence2(tok, state);
11611161
}
11621162
compileUnaryOp(newtok, state, nullptr);
1163+
if (Token::simpleMatch(newtok->previous(), ":: new")) {
1164+
newtok->previous()->astOperand1(newtok);
1165+
state.op.pop();
1166+
}
11631167
if (innertype && Token::simpleMatch(tok, ") ,"))
11641168
tok = tok->next();
11651169
} else if (state.cpp && Token::Match(tok, "delete %name%|*|&|::|(|[")) {
@@ -1169,6 +1173,10 @@ static void compilePrecedence3(Token *&tok, AST_state& state)
11691173
tok = tok->link()->next();
11701174
compilePrecedence3(tok, state);
11711175
compileUnaryOp(tok2, state, nullptr);
1176+
if (Token::simpleMatch(tok2->previous(), ":: delete")) {
1177+
tok2->previous()->astOperand1(tok2);
1178+
state.op.pop();
1179+
}
11721180
}
11731181
// TODO: Handle sizeof
11741182
else break;

test/testtokenize.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6251,6 +6251,8 @@ class TestTokenizer : public TestFixture {
62516251
ASSERT_EQUALS("pint5[{new=", testAst("p = new int* [5]{};"));
62526252
ASSERT_EQUALS("pint5[0{new=", testAst("p = new int* [5]{ 0 };"));
62536253
ASSERT_EQUALS("sSint(new::(new=", testAst("s = new S(::new int());")); // #12502
6254+
ASSERT_EQUALS("sS(new::=", testAst("s = ::new (ptr) S();")); // #12552
6255+
ASSERT_EQUALS("pdelete::return", testAst("return ::delete p;"));
62546256

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

70857087
ASSERT_THROW(tokenizeAndStringify("{ for (()()) }"), InternalError); // #11643
7088+
7089+
ASSERT_NO_THROW(tokenizeAndStringify("S* g = ::new(ptr) S();")); // #12552
7090+
ASSERT_NO_THROW(tokenizeAndStringify("void f(int* p) { return ::delete p; }"));
70867091
}
70877092

70887093

0 commit comments

Comments
 (0)