Skip to content

Commit 67f4fe5

Browse files
Fix #10978 syntaxError with attribute for function pointer (#4069)
1 parent 6c54e73 commit 67f4fe5

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

lib/tokenize.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10978,7 +10978,7 @@ void Tokenizer::simplifyAttribute()
1097810978
syntaxError(tok);
1097910979

1098010980
Token *functok = nullptr;
10981-
if (Token::Match(after, "%name%|*")) {
10981+
if (Token::Match(after, "%name%|*|(")) {
1098210982
Token *ftok = after;
1098310983
while (Token::Match(ftok, "%name%|::|<|* !!(")) {
1098410984
if (ftok->str() == "<") {
@@ -10988,7 +10988,9 @@ void Tokenizer::simplifyAttribute()
1098810988
}
1098910989
ftok = ftok->next();
1099010990
}
10991-
if (Token::Match(ftok, "%name% ("))
10991+
if (Token::simpleMatch(ftok, "( *"))
10992+
ftok = ftok->tokAt(2);
10993+
if (Token::Match(ftok, "%name% (|)"))
1099210994
functok = ftok;
1099310995
} else if (Token::Match(after, "[;{=:]")) {
1099410996
Token *prev = tok->previous();

test/testtokenize.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ class TestTokenizer : public TestFixture {
263263
TEST_CASE(removeattribute);
264264
TEST_CASE(functionAttributeBefore1);
265265
TEST_CASE(functionAttributeBefore2);
266+
TEST_CASE(functionAttributeBefore3);
266267
TEST_CASE(functionAttributeAfter);
267268
TEST_CASE(functionAttributeListBefore);
268269
TEST_CASE(functionAttributeListAfter);
@@ -3653,6 +3654,22 @@ class TestTokenizer : public TestFixture {
36533654
ASSERT(VAS_Fail && VAS_Fail->isAttributeNoreturn());
36543655
}
36553656

3657+
void functionAttributeBefore3() { // #10978
3658+
const char code[] = "void __attribute__((__noreturn__)) (*func_notret)(void);";
3659+
const char expected[] = "void ( * func_notret ) ( ) ;";
3660+
3661+
errout.str("");
3662+
3663+
// tokenize..
3664+
Tokenizer tokenizer(&settings0, this);
3665+
std::istringstream istr(code);
3666+
ASSERT(tokenizer.tokenize(istr, "test.cpp"));
3667+
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));
3668+
3669+
const Token* func_notret = Token::findsimplematch(tokenizer.tokens(), "func_notret");
3670+
ASSERT(func_notret && func_notret->isAttributeNoreturn());
3671+
}
3672+
36563673
void functionAttributeAfter() {
36573674
const char code[] = "void func1() __attribute__((pure)) __attribute__((nothrow)) __attribute__((const));\n"
36583675
"void func2() __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__));\n"

0 commit comments

Comments
 (0)