diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 870b6e1d4..238857fea 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -704,6 +704,8 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const if (type == Variables::none || isPartOfClassStructUnion(i->typeStartToken())) continue; const Token* defValTok = i->nameToken()->next(); + if (Token::Match(i->nameToken()->previous(), "* %var% ) (")) // function pointer. Jump behind parameter list. + defValTok = defValTok->linkAt(1)->next(); for (; defValTok; defValTok = defValTok->next()) { if (defValTok->str() == "[") defValTok = defValTok->link(); diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 27017a531..cab63cca6 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -157,6 +157,7 @@ private: TEST_CASE(localvarRangeBasedFor); // #7075 TEST_CASE(localvarAssignInWhile); TEST_CASE(localvarTemplate); // #4955 - variable is used as template parameter + TEST_CASE(localvarFuncPtr); // #7194 TEST_CASE(localvarCppInitialization); TEST_CASE(localvarCpp11Initialization); @@ -3885,6 +3886,30 @@ private: ASSERT_EQUALS("", errout.str()); } + void localvarFuncPtr() { + functionVariableUsage("int main() {\n" + " void(*funcPtr)(void)(x);\n" + "}"); + TODO_ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'funcPtr' is assigned a value never used.\n", "", errout.str()); + + functionVariableUsage("int main() {\n" + " void(*funcPtr)(void);\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (style) Unused variable: funcPtr\n", errout.str()); + + functionVariableUsage("int main() {\n" + " void(*funcPtr)(void)(x);\n" + " funcPtr();\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + functionVariableUsage("int main() {\n" + " void(*funcPtr)(void) = x;\n" + " funcPtr();\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void chainedAssignment() { // #5466 functionVariableUsage("void NotUsed(double* pdD, int n) {\n"