diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 9ff9243cf..c881087b7 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10748,32 +10748,54 @@ void Tokenizer::removeUnnecessaryQualification() if (tok == classInfo.back().classEnd) classInfo.pop_back(); else if (tok->str() == classInfo.back().className && - Token::Match(tok, "%type% :: %type% (") && - Token::Match(tok->tokAt(3)->link(), ") const| {|;|:") && - tok->previous()->str() != ":" && !classInfo.back().isNamespace) + !classInfo.back().isNamespace && tok->previous()->str() != ":" && + (Token::Match(tok, "%type% :: %type% (") || + Token::Match(tok, "%type% :: operator"))) { - std::string qualification = tok->str() + "::"; - - // check for extra qualification - /** @todo this should be made more generic to handle more levels */ - if (Token::Match(tok->tokAt(-2), "%type% ::")) + int offset = 3; + if (tok->strAt(2) == "operator") { - if (classInfo.size() >= 2) + const Token *tok1 = tok->tokAt(offset); + + // check for operator () + if (tok1->str() == "(") { - if (classInfo.at(classInfo.size() - 2).className != tok->strAt(-2)) - continue; - else - qualification = tok->strAt(-2) + "::" + qualification; + tok1 = tok1->next(); + offset++; + } + + while (tok1 && tok1->str() != "(") + { + tok1 = tok1->next(); + offset++; } - else - continue; } - if (_settings && _settings->isEnabled("portability")) - unnecessaryQualificationError(tok, qualification); + if (Token::Match(tok->tokAt(offset)->link(), ") const| {|;|:")) + { + std::string qualification = tok->str() + "::"; - tok->deleteThis(); - tok->deleteThis(); + // check for extra qualification + /** @todo this should be made more generic to handle more levels */ + if (Token::Match(tok->tokAt(-2), "%type% ::")) + { + if (classInfo.size() >= 2) + { + if (classInfo.at(classInfo.size() - 2).className != tok->strAt(-2)) + continue; + else + qualification = tok->strAt(-2) + "::" + qualification; + } + else + continue; + } + + if (_settings && _settings->isEnabled("portability")) + unnecessaryQualificationError(tok, qualification); + + tok->deleteThis(); + tok->deleteThis(); + } } } } diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 64a4de1f3..17c8e94fe 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -371,6 +371,7 @@ private: TEST_CASE(removeUnnecessaryQualification5); TEST_CASE(removeUnnecessaryQualification6); // ticket #2859 TEST_CASE(removeUnnecessaryQualification7); // ticket #2970 + TEST_CASE(removeUnnecessaryQualification8); TEST_CASE(simplifyIfNotNull); TEST_CASE(simplifyVarDecl1); // ticket # 2682 segmentation fault @@ -7341,11 +7342,25 @@ private: " TProcedure::TProcedure(long endAddress) : m_lEndAddr(endAddress){}\n" "private:\n" " long m_lEndAddr;\n" - "}\n"; + "};\n"; tok(code, false); ASSERT_EQUALS("[test.cpp:3]: (portability) Extra qualification 'TProcedure::' unnecessary and considered an error by many compilers.\n", errout.str()); } + void removeUnnecessaryQualification8() + { + const char code[] = "class Fred {\n" + "public:\n" + " Fred & Fred::operator = (const Fred &);\n" + " void Fred::operator () (void);\n" + " void Fred::operator delete[](void* x);\n" + "};\n"; + tok(code, false); + ASSERT_EQUALS("[test.cpp:3]: (portability) Extra qualification 'Fred::' unnecessary and considered an error by many compilers.\n" + "[test.cpp:4]: (portability) Extra qualification 'Fred::' unnecessary and considered an error by many compilers.\n" + "[test.cpp:5]: (portability) Extra qualification 'Fred::' unnecessary and considered an error by many compilers.\n", errout.str()); + } + void simplifyIfNotNull() { {