Skip to content

Commit b8c5426

Browse files
committed
fix danmar#2567 Unused private function when implemented in different file
1 parent b3e8ef9 commit b8c5426

File tree

2 files changed

+42
-79
lines changed

2 files changed

+42
-79
lines changed

lib/checkclass.cpp

Lines changed: 20 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,9 @@ void CheckClass::privateFunctions()
610610
if (!func->hasBody)
611611
{
612612
// empty private copy constructors and assignment operators are OK
613-
if ((func->type == Function::eCopyConstructor || func->type == Function::eOperatorEqual) && func->access == Private)
613+
if ((func->type == Function::eCopyConstructor ||
614+
func->type == Function::eOperatorEqual) &&
615+
func->access == Private)
614616
continue;
615617

616618
whole = false;
@@ -630,98 +632,37 @@ void CheckClass::privateFunctions()
630632
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
631633
{
632634
// Get private functions..
633-
if (func->type == Function::eFunction &&
634-
func->access == Private && func->hasBody)
635+
if (func->type == Function::eFunction && func->access == Private)
635636
FuncList.push_back(func->tokenDef);
636637
}
637638
}
638639

639640
// Check that all private functions are used..
640-
bool HasFuncImpl = false;
641-
bool inclass = false;
642-
int indent_level = 0;
643-
for (const Token *ftok = _tokenizer->tokens(); ftok; ftok = ftok->next())
641+
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func)
644642
{
645-
if (ftok->str() == "{")
646-
++indent_level;
647-
else if (ftok->str() == "}")
648-
{
649-
if (indent_level > 0)
650-
--indent_level;
651-
if (indent_level == 0)
652-
inclass = false;
653-
}
654-
655-
else if (ftok->str() == "class" &&
656-
ftok->next()->str() == classname &&
657-
Token::Match(ftok->tokAt(2), ":|{"))
658-
{
659-
indent_level = 0;
660-
inclass = true;
661-
}
662-
663-
// Check member class functions to see what functions are used..
664-
else if ((inclass && indent_level == 1 && Token::Match(ftok, "%var% (")) ||
665-
(ftok->str() == classname && Token::Match(ftok->next(), ":: ~| %var% (")))
643+
const Token *ftok = func->arg->link()->next();
644+
while (ftok->str() != "{")
645+
ftok = ftok->next();
646+
const Token *etok = ftok->link();
647+
648+
for (; ftok != etok; ftok = ftok->next())
666649
{
667-
while (ftok && ftok->str() != ")")
668-
ftok = ftok->next();
669-
if (!ftok)
670-
break;
671-
if (Token::Match(ftok, ") : %var% ("))
650+
if (Token::Match(ftok, "%var% ("))
672651
{
673-
while (!Token::Match(ftok->next(), "[{};]"))
652+
// Remove function from FuncList
653+
std::list<const Token *>::iterator it = FuncList.begin();
654+
while (it != FuncList.end())
674655
{
675-
if (Token::Match(ftok, "::|,|( %var% ,|)"))
676-
{
677-
// Remove function from FuncList
678-
std::list<const Token *>::iterator it = FuncList.begin();
679-
while (it != FuncList.end())
680-
{
681-
if (ftok->next()->str() == (*it)->str())
682-
FuncList.erase(it++);
683-
else
684-
++it;
685-
}
686-
}
687-
ftok = ftok->next();
688-
}
689-
}
690-
if (!Token::Match(ftok, ") const| {"))
691-
continue;
692-
693-
if (ftok->fileIndex() == 0)
694-
HasFuncImpl = true;
695-
696-
// Parse function..
697-
int indentlevel2 = 0;
698-
for (const Token *tok2 = ftok; tok2; tok2 = tok2->next())
699-
{
700-
if (tok2->str() == "{")
701-
++indentlevel2;
702-
else if (tok2->str() == "}")
703-
{
704-
--indentlevel2;
705-
if (indentlevel2 < 1)
706-
break;
707-
}
708-
else if (Token::Match(tok2, "%var% ("))
709-
{
710-
// Remove function from FuncList
711-
std::list<const Token *>::iterator it = FuncList.begin();
712-
while (it != FuncList.end())
713-
{
714-
if (tok2->str() == (*it)->str())
715-
FuncList.erase(it++);
716-
else
717-
++it;
718-
}
656+
if (ftok->str() == (*it)->str())
657+
FuncList.erase(it++);
658+
else
659+
++it;
719660
}
720661
}
721662
}
722663
}
723664

724-
while (HasFuncImpl && !FuncList.empty())
665+
while (!FuncList.empty())
725666
{
726667
// Final check; check if the function pointer is used somewhere..
727668
const std::string _pattern("return|(|)|,|= " + FuncList.front()->str());

test/testunusedprivfunc.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ class TestUnusedPrivateFunction : public TestFixture
6565
TEST_CASE(testDoesNotIdentifyMethodAsFirstFunctionArgument); // #2480
6666
TEST_CASE(testDoesNotIdentifyMethodAsMiddleFunctionArgument);
6767
TEST_CASE(testDoesNotIdentifyMethodAsLastFunctionArgument);
68+
69+
TEST_CASE(multiFile);
6870
}
6971

7072

@@ -549,6 +551,26 @@ class TestUnusedPrivateFunction : public TestFixture
549551
);
550552
ASSERT_EQUALS("", errout.str());
551553
}
554+
555+
void multiFile() // ticket #2567
556+
{
557+
check("#file \"test.h\"\n"
558+
"struct Fred\n"
559+
"{\n"
560+
" Fred()\n"
561+
" {\n"
562+
" Init();\n"
563+
" }\n"
564+
"private:\n"
565+
" void Init();\n"
566+
"};\n"
567+
"#endfile\n"
568+
"void Fred::Init()\n"
569+
"{\n"
570+
"}\n");
571+
572+
ASSERT_EQUALS("", errout.str());
573+
}
552574
};
553575

554576
REGISTER_TEST(TestUnusedPrivateFunction)

0 commit comments

Comments
 (0)