Skip to content

Commit 7449640

Browse files
authored
Fix #15079 FP syntaxError for C-style cast before scope operator (#8909)
1 parent abef304 commit 7449640

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

‎lib/tokenize.cpp‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9178,9 +9178,11 @@ void Tokenizer::findGarbageCode() const
91789178
if (!Token::Match(tok->next(), "%name%|*|~") || (tok->next()->isKeyword() && !Token::Match(tok->next(), "new|delete|operator")))
91799179
syntaxError(tok);
91809180
if (Token::simpleMatch(tok->tokAt(-1), ")")) {
9181+
// NAME(...):: => NAME is most likely an unknown macro
9182+
// other cases are valid, e.g. (void)::f(), return (T)::x, new (p) ::T, decltype(x)::type
91819183
const Token* const prev = tok->linkAt(-1)->tokAt(-1);
9182-
if (!Token::Match(prev, "%name% (") || (!prev->isControlFlowKeyword() && prev->str() != "decltype")) {
9183-
if (prev && prev->isUpperCaseName())
9184+
if (Token::Match(prev, "%name% (") && !prev->isKeyword() && prev->str() != "decltype") { // decltype is no keyword before C++11
9185+
if (prev->isUpperCaseName())
91849186
unknownMacroError(prev);
91859187
else
91869188
syntaxError(tok);

‎test/testtokenize.cpp‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8135,6 +8135,28 @@ class TestTokenizer : public TestFixture {
81358135
" *p = -*p;\n"
81368136
"}\n"));
81378137

8138+
ASSERT_NO_THROW(tokenizeAndStringify("void f(void* h) {\n" // #15079
8139+
" (void)::CloseHandle(h);\n"
8140+
" int i = (int)::GetTickCount();\n"
8141+
" g((unsigned char)::toupper(i));\n"
8142+
"}\n"));
8143+
ASSERT_NO_THROW(tokenizeAndStringify("int f(int i) {\n"
8144+
" return (int)::abs(i);\n"
8145+
"}\n"));
8146+
ASSERT_NO_THROW(tokenizeAndStringify("namespace N { struct T {}; }\n"
8147+
"void f(void* p) {\n"
8148+
" new (p) ::N::T;\n"
8149+
"}\n"));
8150+
ASSERT_NO_THROW(tokenizeAndStringify("struct S { using type = int; };\n"
8151+
"S s;\n"
8152+
"decltype(s)::type i;\n"));
8153+
{
8154+
const Settings s = settingsBuilder().cpp(Standards::CPP03).build();
8155+
ASSERT_NO_THROW(tokenizeAndStringify("struct S { typedef int type; };\n"
8156+
"S s;\n"
8157+
"decltype(s)::type i;\n", s));
8158+
}
8159+
81388160
ignore_errout();
81398161

81408162
ASSERT_EQUALS(";", tokenizeAndStringify("typedef std::size_t size_t;\n")); // #14809

0 commit comments

Comments
 (0)