diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index 347c23013..6d2faa70e 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -214,7 +214,7 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi funcname = tok->next(); while (Token::Match(funcname, "%name% :: %name%")) funcname = funcname->tokAt(2); - } else if (Token::Match(tok, "[;{}.,()[=+-/|!?:]")) { + } else if (tok->scope()->type != Scope::ScopeType::eEnum && Token::Match(tok, "[;{}.,()[=+-/|!?:]")) { funcname = tok->next(); if (funcname && funcname->str() == "&") funcname = funcname->next(); @@ -305,14 +305,15 @@ static bool isOperatorFunction(const std::string & funcName) bool CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings& settings) const { - bool errors = false; + using ErrorParams = std::tuple; + std::vector errors; // ensure well-defined order + for (std::unordered_map::const_iterator it = mFunctions.cbegin(); it != mFunctions.cend(); ++it) { const FunctionUsage &func = it->second; if (func.usedOtherFile || func.filename.empty()) continue; if (it->first == "main" || - (settings.isWindowsPlatform() && (it->first == "WinMain" || it->first == "_tmain")) || - it->first == "if") + (settings.isWindowsPlatform() && (it->first == "WinMain" || it->first == "_tmain"))) continue; if (!func.usedSameFile) { if (isOperatorFunction(it->first)) @@ -320,8 +321,7 @@ bool CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings std::string filename; if (func.filename != "+") filename = func.filename; - unusedFunctionError(errorLogger, filename, func.lineNumber, it->first); - errors = true; + errors.emplace_back(filename, func.lineNumber, it->first); } else if (!func.usedOtherFile) { /** @todo add error message "function is only used in it can be static" */ /* @@ -332,7 +332,10 @@ bool CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings */ } } - return errors; + std::sort(errors.begin(), errors.end()); + for (const auto& e : errors) + unusedFunctionError(errorLogger, std::get<0>(e), std::get<1>(e), std::get<2>(e)); + return !errors.empty(); } void CheckUnusedFunctions::unusedFunctionError(ErrorLogger * const errorLogger, diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index 61d8941e4..11fa22082 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -61,6 +61,7 @@ private: TEST_CASE(initializer_list); TEST_CASE(member_function_ternary); TEST_CASE(boost); + TEST_CASE(enumValues); TEST_CASE(multipleFiles); // same function name in multiple files @@ -442,6 +443,18 @@ private: ASSERT_EQUALS("", errout.str()); } + void enumValues() { // #11486 + check("enum E1 { Break1 };\n" + "struct S {\n" + " enum class E { Break };\n" + " void Break() {}\n" + " void Break1() {}\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:4]: (style) The function 'Break' is never used.\n" + "[test.cpp:5]: (style) The function 'Break1' is never used.\n", + errout.str()); + } + void multipleFiles() { Tokenizer tokenizer(&settings, this); CheckUnusedFunctions c(&tokenizer, &settings, nullptr);