Skip to content

Commit

Permalink
Fix #8159 FN unusedFunction: sole recursive call (#6517)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github authored Jun 16, 2024
1 parent a5e2456 commit 750b914
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 81 deletions.
7 changes: 7 additions & 0 deletions lib/checkunusedfunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ static std::string stripTemplateParameters(const std::string& funcName) {
// FUNCTION USAGE - Check for unused functions etc
//---------------------------------------------------------------------------

static bool isRecursiveCall(const Token* ftok)
{
return ftok->function() && ftok->function() == Scope::nestedInFunction(ftok->scope());
}

void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Settings &settings)
{
const char * const FileName = tokenizer.list.getFiles().front().c_str();
Expand Down Expand Up @@ -245,6 +250,8 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Setting
}

if (funcname) {
if (isRecursiveCall(funcname))
continue;
const auto baseName = stripTemplateParameters(funcname->str());
FunctionUsage &func = mFunctions[baseName];
const std::string& called_from_file = tokenizer.list.getFiles()[funcname->fileIndex()];
Expand Down
3 changes: 2 additions & 1 deletion lib/clangimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ namespace clangimport {

void dumpAst(int num = 0, int indent = 0) const;
void createTokens1(TokenList &tokenList) {
//dumpAst();
//dumpAst(); // TODO: reactivate or remove
if (!tokenList.back()) {
setLocations(tokenList, 0, 1, 1);
// FIXME: treat as C++ if no filename (i.e. no lang) is specified for now
Expand Down Expand Up @@ -486,6 +486,7 @@ std::string clangimport::AstNode::getTemplateParameters() const
return templateParameters + ">";
}

// cppcheck-suppress unusedFunction // only used in comment
void clangimport::AstNode::dumpAst(int num, int indent) const
{
(void)num;
Expand Down
38 changes: 0 additions & 38 deletions lib/mathlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1274,44 +1274,6 @@ bool MathLib::isOctalDigit(char c)
return (c >= '0' && c <= '7');
}

bool MathLib::isDigitSeparator(const std::string& iCode, std::string::size_type iPos)
{
if (iPos == 0 || iPos >= iCode.size() || iCode[iPos] != '\'')
return false;
std::string::size_type i = iPos - 1;
while (std::isxdigit(iCode[i])) {
if (i == 0)
return true; // Only xdigits before '
--i;
}
if (i == iPos - 1) // No xdigit before '
return false;

switch (iCode[i]) {
case ' ':
case '.':
case ',':
case 'x':
case '(':
case '{':
case '+':
case '-':
case '*':
case '%':
case '/':
case '&':
case '|':
case '^':
case '~':
case '=':
return true;
case '\'':
return isDigitSeparator(iCode, i);
default:
return false;
}
}

MathLib::value operator+(const MathLib::value &v1, const MathLib::value &v2)
{
return MathLib::value::calc('+',v1,v2);
Expand Down
7 changes: 0 additions & 7 deletions lib/mathlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,6 @@ class CPPCHECKLIB MathLib {
static bool isOctalDigit(char c);

static unsigned int encodeMultiChar(const std::string& str);

/**
* \param[in] iCode Code being considered
* \param[in] iPos A posision within iCode
* \return Whether iCode[iPos] is a C++14 digit separator
*/
static bool isDigitSeparator(const std::string& iCode, std::string::size_type iPos);
};

MathLib::value operator+(const MathLib::value &v1, const MathLib::value &v2);
Expand Down
2 changes: 1 addition & 1 deletion lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1152,7 +1152,7 @@ void SymbolDatabase::createSymbolDatabaseSetFunctionPointers(bool firstPass)
inTemplateArg = tok->link();
if (inTemplateArg == tok)
inTemplateArg = nullptr;
if (tok->isName() && !tok->function() && tok->varId() == 0 && ((tok->astParent() && tok->astParent()->isComparisonOp()) || Token::Match(tok, "%name% [{(,)>;]]")) && !isReservedName(tok)) {
if (tok->isName() && !tok->function() && tok->varId() == 0 && ((tok->astParent() && tok->astParent()->isComparisonOp()) || Token::Match(tok, "%name% [{(,)>;:]]")) && !isReservedName(tok)) {
if (tok->strAt(1) == ">" && !tok->linkAt(1))
continue;

Expand Down
1 change: 1 addition & 0 deletions lib/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1702,6 +1702,7 @@ std::string Token::astStringVerbose() const
return ret;
}

// cppcheck-suppress unusedFunction // used in test
std::string Token::astStringZ3() const
{
if (!astOperand1())
Expand Down
19 changes: 0 additions & 19 deletions test/testmathlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ class TestMathLib : public TestFixture {
TEST_CASE(tan);
TEST_CASE(abs);
TEST_CASE(toString);
TEST_CASE(CPP14DigitSeparators);
}

void isGreater() const {
Expand Down Expand Up @@ -1475,24 +1474,6 @@ class TestMathLib : public TestFixture {
ASSERT_EQUALS("2.22507385851e-308", MathLib::toString(std::numeric_limits<double>::min()));
ASSERT_EQUALS("1.79769313486e+308", MathLib::toString(std::numeric_limits<double>::max()));
}

void CPP14DigitSeparators() const { // Ticket #7137, #7565
ASSERT(MathLib::isDigitSeparator("'", 0) == false);
ASSERT(MathLib::isDigitSeparator("123'0;", 3));
ASSERT(MathLib::isDigitSeparator("foo(1'2);", 5));
ASSERT(MathLib::isDigitSeparator("foo(1,1'2);", 7));
ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 7));
ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 13));
ASSERT(MathLib::isDigitSeparator("int a=1'234-1'2-'0';", 16) == false);
ASSERT(MathLib::isDigitSeparator("int b=1+9'8;", 9));
ASSERT(MathLib::isDigitSeparator("if (1'2) { char c = 'c'; }", 5));
ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 9));
ASSERT(MathLib::isDigitSeparator("if (120&1'2) { char c = 'c'; }", 9));
ASSERT(MathLib::isDigitSeparator("if (120|1'2) { char c = 'c'; }", 9));
ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 24) == false);
ASSERT(MathLib::isDigitSeparator("if (120%1'2) { char c = 'c'; }", 26) == false);
ASSERT(MathLib::isDigitSeparator("0b0000001'0010'01110", 14));
}
};

REGISTER_TEST(TestMathLib)
40 changes: 25 additions & 15 deletions test/testunusedfunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class TestUnusedFunctions : public TestFixture {
TEST_CASE(member_function_ternary);
TEST_CASE(boost);
TEST_CASE(enumValues);
TEST_CASE(recursive);

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

Expand Down Expand Up @@ -116,23 +117,23 @@ class TestUnusedFunctions : public TestFixture {
" if (f1())\n"
" { }\n"
"}");
ASSERT_EQUALS("", errout_str());
ASSERT_EQUALS("[test.cpp:1]: (style) The function 'f1' is never used.\n", errout_str());
}

void return1() {
check("int f1()\n"
"{\n"
" return f1();\n"
"}");
ASSERT_EQUALS("", errout_str());
ASSERT_EQUALS("[test.cpp:1]: (style) The function 'f1' is never used.\n", errout_str());
}

void return2() {
check("char * foo()\n"
"{\n"
" return *foo();\n"
" return foo();\n"
"}");
ASSERT_EQUALS("", errout_str());
ASSERT_EQUALS("[test.cpp:1]: (style) The function 'foo' is never used.\n", errout_str());
}

void return3() {
Expand All @@ -158,7 +159,7 @@ class TestUnusedFunctions : public TestFixture {
"{\n"
" void (*f)() = cond ? f1 : NULL;\n"
"}");
ASSERT_EQUALS("", errout_str());
ASSERT_EQUALS("[test.cpp:1]: (style) The function 'f1' is never used.\n", errout_str());
}

void callback2() { // #8677
Expand All @@ -180,7 +181,7 @@ class TestUnusedFunctions : public TestFixture {
" if (cond) ;\n"
" else f1();\n"
"}");
ASSERT_EQUALS("", errout_str());
ASSERT_EQUALS("[test.cpp:1]: (style) The function 'f1' is never used.\n", errout_str());
}

void functionpointer() {
Expand Down Expand Up @@ -255,7 +256,7 @@ class TestUnusedFunctions : public TestFixture {
"}\n"
"\n"
"void h() { g<int>(); h(); }");
ASSERT_EQUALS("", errout_str());
ASSERT_EQUALS("[test.cpp:8]: (style) The function 'h' is never used.\n", errout_str());
}

void template3() { // #4701
Expand Down Expand Up @@ -286,7 +287,7 @@ class TestUnusedFunctions : public TestFixture {
" test();\n"
" }\n"
"};");
ASSERT_EQUALS("", errout_str());
ASSERT_EQUALS("[test.cpp:11]: (style) The function 'test' is never used.\n", errout_str());
}

void template5() { // #9220
Expand Down Expand Up @@ -322,7 +323,7 @@ class TestUnusedFunctions : public TestFixture {
"};\n");
ASSERT_EQUALS("[test.cpp:3]: (style) The function 'tf' is never used.\n", errout_str());

check("struct S {\n"
check("struct C {\n"
" template<typename T>\n"
" void tf(const T&) { }\n"
"};\n"
Expand All @@ -332,7 +333,7 @@ class TestUnusedFunctions : public TestFixture {
"}\n");
ASSERT_EQUALS("", errout_str());

check("struct S {\n"
check("struct C {\n"
" template<typename T>\n"
" void tf(const T&) { }\n"
"};\n"
Expand Down Expand Up @@ -523,10 +524,11 @@ class TestUnusedFunctions : public TestFixture {
}

void boost() {
check("static void _xy(const char *b, const char *e)\n"
"{}\n"
"parse(line, blanks_p >> ident[&_xy] >> blanks_p >> eol_p).full");
ASSERT_EQUALS("", errout_str());
check("static void _xy(const char *b, const char *e) {}\n"
"void f() {\n"
" parse(line, blanks_p >> ident[&_xy] >> blanks_p >> eol_p).full;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2]: (style) The function 'f' is never used.\n", errout_str());
}

void enumValues() { // #11486
Expand All @@ -541,6 +543,14 @@ class TestUnusedFunctions : public TestFixture {
errout_str());
}

void recursive() {
check("void f() {\n" // #8159
" f();\n"
"}\n");
ASSERT_EQUALS("[test.cpp:1]: (style) The function 'f' is never used.\n",
errout_str());
}

void multipleFiles() {
CheckUnusedFunctions c;

Expand Down Expand Up @@ -576,7 +586,7 @@ class TestUnusedFunctions : public TestFixture {
ASSERT_EQUALS("[test.cpp:2]: (style) The function 'f' is never used.\n", errout_str());

check("void f(void) {}\n"
"void (*list[])(void) = {f}");
"void (*list[])(void) = {f};");
ASSERT_EQUALS("", errout_str());
}

Expand Down

0 comments on commit 750b914

Please sign in to comment.