Skip to content

Commit

Permalink
Tokenizer: Fix handling of __attribute__ for overloaded operator func…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
danmar committed May 8, 2022
1 parent b847882 commit eb9c4b4
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
2 changes: 2 additions & 0 deletions lib/tokenize.cpp
Expand Up @@ -11001,6 +11001,8 @@ void Tokenizer::simplifyAttribute()
prev = prev->previous();
if (Token::simpleMatch(prev, ")") && Token::Match(prev->link()->previous(), "%name% ("))
functok = prev->link()->previous();
else if (Token::simpleMatch(prev, ")") && Token::Match(prev->link()->tokAt(-2), "operator %op% (") && isCPP())
functok = prev->link()->tokAt(-2);
else if ((!prev || Token::Match(prev, "[;{}*]")) && Token::Match(tok->previous(), "%name%"))
functok = tok->previous();
}
Expand Down
26 changes: 24 additions & 2 deletions test/testtokenize.cpp
Expand Up @@ -264,7 +264,8 @@ class TestTokenizer : public TestFixture {
TEST_CASE(functionAttributeBefore1);
TEST_CASE(functionAttributeBefore2);
TEST_CASE(functionAttributeBefore3);
TEST_CASE(functionAttributeAfter);
TEST_CASE(functionAttributeAfter1);
TEST_CASE(functionAttributeAfter2);
TEST_CASE(functionAttributeListBefore);
TEST_CASE(functionAttributeListAfter);

Expand Down Expand Up @@ -3672,7 +3673,7 @@ class TestTokenizer : public TestFixture {
ASSERT(func_notret && func_notret->isAttributeNoreturn());
}

void functionAttributeAfter() {
void functionAttributeAfter1() {
const char code[] = "void func1() __attribute__((pure)) __attribute__((nothrow)) __attribute__((const));\n"
"void func2() __attribute__((__pure__)) __attribute__((__nothrow__)) __attribute__((__const__));\n"
"void func3() __attribute__((nothrow)) __attribute__((pure)) __attribute__((const));\n"
Expand Down Expand Up @@ -3703,6 +3704,27 @@ class TestTokenizer : public TestFixture {
ASSERT(func5 && func5->isAttributeNoreturn());
}

void functionAttributeAfter2() {
const char code[] = "class foo {\n"
"public:\n"
" bool operator==(const foo &) __attribute__((__pure__));\n"
"};";
const char expected[] = "class foo { public: bool operator== ( const foo & ) ; } ;";

errout.str("");

// tokenize..
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
ASSERT(tokenizer.tokenize(istr, "test.cpp"));

// Expected result..
ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false));

const Token *tok = Token::findsimplematch(tokenizer.tokens(), "operator==");
ASSERT(tok && tok->isAttributePure());
}

void functionAttributeListBefore() {
const char code[] = "void __attribute__((pure,nothrow,const)) func1();\n"
"void __attribute__((__pure__,__nothrow__,__const__)) func2();\n"
Expand Down

0 comments on commit eb9c4b4

Please sign in to comment.