Skip to content

Commit 911d610

Browse files
Fix #11486 FN unusedFunction when enum value with same name exists (#4690)
1 parent cefc105 commit 911d610

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

lib/checkunusedfunctions.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi
214214
funcname = tok->next();
215215
while (Token::Match(funcname, "%name% :: %name%"))
216216
funcname = funcname->tokAt(2);
217-
} else if (Token::Match(tok, "[;{}.,()[=+-/|!?:]")) {
217+
} else if (tok->scope()->type != Scope::ScopeType::eEnum && Token::Match(tok, "[;{}.,()[=+-/|!?:]")) {
218218
funcname = tok->next();
219219
if (funcname && funcname->str() == "&")
220220
funcname = funcname->next();
@@ -305,23 +305,23 @@ static bool isOperatorFunction(const std::string & funcName)
305305

306306
bool CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings& settings) const
307307
{
308-
bool errors = false;
308+
using ErrorParams = std::tuple<std::string, unsigned int, std::string>;
309+
std::vector<ErrorParams> errors; // ensure well-defined order
310+
309311
for (std::unordered_map<std::string, FunctionUsage>::const_iterator it = mFunctions.cbegin(); it != mFunctions.cend(); ++it) {
310312
const FunctionUsage &func = it->second;
311313
if (func.usedOtherFile || func.filename.empty())
312314
continue;
313315
if (it->first == "main" ||
314-
(settings.isWindowsPlatform() && (it->first == "WinMain" || it->first == "_tmain")) ||
315-
it->first == "if")
316+
(settings.isWindowsPlatform() && (it->first == "WinMain" || it->first == "_tmain")))
316317
continue;
317318
if (!func.usedSameFile) {
318319
if (isOperatorFunction(it->first))
319320
continue;
320321
std::string filename;
321322
if (func.filename != "+")
322323
filename = func.filename;
323-
unusedFunctionError(errorLogger, filename, func.lineNumber, it->first);
324-
errors = true;
324+
errors.emplace_back(filename, func.lineNumber, it->first);
325325
} else if (!func.usedOtherFile) {
326326
/** @todo add error message "function is only used in <file> it can be static" */
327327
/*
@@ -332,7 +332,10 @@ bool CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings
332332
*/
333333
}
334334
}
335-
return errors;
335+
std::sort(errors.begin(), errors.end());
336+
for (const auto& e : errors)
337+
unusedFunctionError(errorLogger, std::get<0>(e), std::get<1>(e), std::get<2>(e));
338+
return !errors.empty();
336339
}
337340

338341
void CheckUnusedFunctions::unusedFunctionError(ErrorLogger * const errorLogger,

test/testunusedfunctions.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class TestUnusedFunctions : public TestFixture {
6161
TEST_CASE(initializer_list);
6262
TEST_CASE(member_function_ternary);
6363
TEST_CASE(boost);
64+
TEST_CASE(enumValues);
6465

6566
TEST_CASE(multipleFiles); // same function name in multiple files
6667

@@ -442,6 +443,18 @@ class TestUnusedFunctions : public TestFixture {
442443
ASSERT_EQUALS("", errout.str());
443444
}
444445

446+
void enumValues() { // #11486
447+
check("enum E1 { Break1 };\n"
448+
"struct S {\n"
449+
" enum class E { Break };\n"
450+
" void Break() {}\n"
451+
" void Break1() {}\n"
452+
"};\n");
453+
ASSERT_EQUALS("[test.cpp:4]: (style) The function 'Break' is never used.\n"
454+
"[test.cpp:5]: (style) The function 'Break1' is never used.\n",
455+
errout.str());
456+
}
457+
445458
void multipleFiles() {
446459
Tokenizer tokenizer(&settings, this);
447460
CheckUnusedFunctions c(&tokenizer, &settings, nullptr);

0 commit comments

Comments
 (0)