unused private function: Handle 'embedded' function implementations better
This commit is contained in:
parent
4849aaa7ee
commit
dac1e91013
|
@ -521,58 +521,68 @@ void CheckClass::privateFunctions()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that all private functions are used..
|
// Check that all private functions are used..
|
||||||
const std::string pattern_function(classname + " ::");
|
|
||||||
bool HasFuncImpl = false;
|
bool HasFuncImpl = false;
|
||||||
const Token *ftok = _tokenizer->tokens();
|
bool inclass = false;
|
||||||
while (ftok)
|
|
||||||
{
|
|
||||||
ftok = Token::findmatch(ftok, pattern_function.c_str());
|
|
||||||
int numpar = 0;
|
|
||||||
while (ftok && !Token::Match(ftok, "[;{]"))
|
|
||||||
{
|
|
||||||
if (ftok->str() == "(")
|
|
||||||
++numpar;
|
|
||||||
else if (ftok->str() == ")")
|
|
||||||
--numpar;
|
|
||||||
ftok = ftok->next();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ftok)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (ftok->str() != ";" && numpar == 0)
|
|
||||||
{
|
|
||||||
HasFuncImpl = true;
|
|
||||||
|
|
||||||
indent_level = 0;
|
indent_level = 0;
|
||||||
while (ftok)
|
const std::string pattern_function(classname + " ::");
|
||||||
|
for (const Token *ftok = _tokenizer->tokens(); ftok; ftok = ftok->next())
|
||||||
{
|
{
|
||||||
if (ftok->str() == "{")
|
if (ftok->str() == "{")
|
||||||
++indent_level;
|
++indent_level;
|
||||||
else if (ftok->str() == "}")
|
else if (ftok->str() == "}")
|
||||||
{
|
{
|
||||||
if (indent_level <= 1)
|
if (indent_level > 0)
|
||||||
break;
|
|
||||||
--indent_level;
|
--indent_level;
|
||||||
|
if (indent_level == 0)
|
||||||
|
inclass = false;
|
||||||
}
|
}
|
||||||
else if (Token::Match(ftok, "%var% ("))
|
|
||||||
|
if (Token::Match(ftok, ("class " + classname + " :|{").c_str()))
|
||||||
|
{
|
||||||
|
indent_level = 0;
|
||||||
|
inclass = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check member class functions to see what functions are used..
|
||||||
|
if ((inclass && indent_level == 1 && Token::Match(ftok, ") const| {")) ||
|
||||||
|
(Token::Match(ftok, (classname + " :: %var% (").c_str())))
|
||||||
|
{
|
||||||
|
while (ftok && ftok->str() != ")")
|
||||||
|
ftok = ftok->next();
|
||||||
|
if (!ftok)
|
||||||
|
break;
|
||||||
|
if (!Token::Match(ftok, ") const| {"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ftok->fileIndex() == 0)
|
||||||
|
HasFuncImpl = true;
|
||||||
|
|
||||||
|
// Parse function..
|
||||||
|
int indentlevel2 = 0;
|
||||||
|
for (const Token *tok2 = ftok; tok2; tok2 = tok2->next())
|
||||||
|
{
|
||||||
|
if (tok2->str() == "{")
|
||||||
|
++indentlevel2;
|
||||||
|
else if (tok2->str() == "}")
|
||||||
|
{
|
||||||
|
--indentlevel2;
|
||||||
|
if (indentlevel2 < 1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (Token::Match(tok2, "%var% ("))
|
||||||
{
|
{
|
||||||
// Remove function from FuncList
|
// Remove function from FuncList
|
||||||
for (std::list<const Token *>::iterator it = FuncList.begin(); it != FuncList.end(); ++it)
|
for (std::list<const Token *>::iterator it = FuncList.begin(); it != FuncList.end(); ++it)
|
||||||
{
|
{
|
||||||
if (ftok->str() == (*it)->str())
|
if (tok2->str() == (*it)->str())
|
||||||
{
|
{
|
||||||
FuncList.remove(*it);
|
FuncList.remove(*it);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ftok = ftok->next();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftok)
|
|
||||||
ftok = ftok->next();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (HasFuncImpl && !FuncList.empty())
|
while (HasFuncImpl && !FuncList.empty())
|
||||||
|
|
|
@ -36,6 +36,7 @@ private:
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
TEST_CASE(test1);
|
TEST_CASE(test1);
|
||||||
|
TEST_CASE(test2);
|
||||||
|
|
||||||
// [ 2236547 ] False positive --style unused function, called via pointer
|
// [ 2236547 ] False positive --style unused function, called via pointer
|
||||||
TEST_CASE(func_pointer);
|
TEST_CASE(func_pointer);
|
||||||
|
@ -81,6 +82,26 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
check("class A {\n"
|
||||||
|
"public:\n"
|
||||||
|
" A();\n"
|
||||||
|
"\n"
|
||||||
|
" void a() const\n"
|
||||||
|
" { b(); }\n"
|
||||||
|
"private:\n"
|
||||||
|
" void b( ) const\n"
|
||||||
|
" { }\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"A::A()\n"
|
||||||
|
"{ }\n");
|
||||||
|
ASSERT_EQUALS(std::string(""), errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue