diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 531cbf35d..dc5b59769 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -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(); } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index fa0e0cfea..c875372c5 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -264,7 +264,8 @@ private: TEST_CASE(functionAttributeBefore1); TEST_CASE(functionAttributeBefore2); TEST_CASE(functionAttributeBefore3); - TEST_CASE(functionAttributeAfter); + TEST_CASE(functionAttributeAfter1); + TEST_CASE(functionAttributeAfter2); TEST_CASE(functionAttributeListBefore); TEST_CASE(functionAttributeListAfter); @@ -3672,7 +3673,7 @@ private: 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" @@ -3703,6 +3704,27 @@ private: 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"