diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index d884834fd..5dba2eda0 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -65,13 +65,8 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi continue; // Don't care about templates - if (tokenizer.isCPP()) { - const Token *retDef = func->retDef; - while (retDef && retDef->isName()) - retDef = retDef->previous(); - if (retDef && retDef->str() == ">") - continue; - } + if (tokenizer.isCPP() && func->templateDef != nullptr) + continue; mFunctionDecl.emplace_back(func); diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index 8382a98b9..ef6280f55 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -46,6 +46,7 @@ private: TEST_CASE(template1); TEST_CASE(template2); TEST_CASE(template3); + TEST_CASE(template4); // #9805 TEST_CASE(throwIsNotAFunction); TEST_CASE(unusedError); TEST_CASE(unusedMain); @@ -229,6 +230,26 @@ private: ASSERT_EQUALS("[test.cpp:3]: (style) The function 'bar' is never used.\n", errout.str()); } + void template4() { // #9805 + check("struct A {\n" + " int a = 0;\n" + " void f() { a = 1; }\n" + " template auto call(const Args &... args) -> T {\n" + " a = 2;\n" + " return T{};\n" + " }\n" + "};\n" + "\n" + "struct B : public A {\n" + " void test() {\n" + " f();\n" + " call(1, 2, 3);\n" + " test();\n" + " }\n" + "};"); + ASSERT_EQUALS("", errout.str()); + } + void throwIsNotAFunction() { check("struct A {void f() const throw () {}}; int main() {A a; a.f();}"); ASSERT_EQUALS("", errout.str());