Fixed #3336 (False positive: Member function is not used (used by template function))

This commit is contained in:
Daniel Marjamäki 2011-12-03 12:19:26 +01:00
parent 1f438b0505
commit b7988a3dab
3 changed files with 23 additions and 2 deletions

View File

@ -33,6 +33,11 @@
void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer) void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer)
{ {
// if there are templates there might be false positives
templates |= tokenizer.codeWithTemplates();
if (templates)
return;
// Function declarations.. // Function declarations..
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) { for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->fileIndex() != 0) if (tok->fileIndex() != 0)
@ -144,6 +149,9 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer)
void CheckUnusedFunctions::check(ErrorLogger * const errorLogger) void CheckUnusedFunctions::check(ErrorLogger * const errorLogger)
{ {
if (templates)
return;
for (std::map<std::string, FunctionUsage>::const_iterator it = _functions.begin(); it != _functions.end(); ++it) { for (std::map<std::string, FunctionUsage>::const_iterator it = _functions.begin(); it != _functions.end(); ++it) {
const FunctionUsage &func = it->second; const FunctionUsage &func = it->second;
if (func.usedOtherFile || func.filename.empty()) if (func.usedOtherFile || func.filename.empty())

View File

@ -32,12 +32,12 @@
class CheckUnusedFunctions: public Check { class CheckUnusedFunctions: public Check {
public: public:
/** @brief This constructor is used when registering the CheckUnusedFunctions */ /** @brief This constructor is used when registering the CheckUnusedFunctions */
CheckUnusedFunctions() : Check(myName()) CheckUnusedFunctions() : Check(myName()), templates(false)
{ } { }
/** @brief This constructor is used when running checks. */ /** @brief This constructor is used when running checks. */
CheckUnusedFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) CheckUnusedFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
: Check(myName(), tokenizer, settings, errorLogger) : Check(myName(), tokenizer, settings, errorLogger), templates(false)
{ } { }
// Parse current tokens and determine.. // Parse current tokens and determine..
@ -88,6 +88,8 @@ private:
}; };
std::map<std::string, FunctionUsage> _functions; std::map<std::string, FunctionUsage> _functions;
bool templates;
}; };
/// @} /// @}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -40,6 +40,7 @@ private:
TEST_CASE(else1); TEST_CASE(else1);
TEST_CASE(functionpointer); TEST_CASE(functionpointer);
TEST_CASE(template1); TEST_CASE(template1);
TEST_CASE(template2);
TEST_CASE(throwIsNotAFunction); TEST_CASE(throwIsNotAFunction);
TEST_CASE(unusedError); TEST_CASE(unusedError);
TEST_CASE(unusedMain); TEST_CASE(unusedMain);
@ -146,6 +147,16 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void template2() {
check("void f() { }\n"
"\n"
"template<class T> void g()\n"
"{\n"
" f();\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void throwIsNotAFunction() { void throwIsNotAFunction() {
check("struct A {void f() const throw () {}}; int main() {A a; a.f();}\n"); check("struct A {void f() const throw () {}}; int main() {A a; a.f();}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());