From eac81707f32809c6901eacb75e384efcbac7f820 Mon Sep 17 00:00:00 2001 From: firewave Date: Sun, 14 Jan 2024 12:31:48 +0100 Subject: [PATCH 1/9] CheckUnusedFunctions: added dedicated `getErrorMessages()` --- lib/checkunusedfunctions.h | 8 +++++--- lib/cppcheck.cpp | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index b7bdee62700..eedf49252be 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -76,12 +76,14 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check { /** @brief Combine and analyze all analyzerInfos for all TUs */ static void analyseWholeProgram(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir); + static void getErrorMessages(ErrorLogger *errorLogger) { + unusedFunctionError(errorLogger, emptyString, 0, 0, "funcName"); + } + private: static void clear(); - void getErrorMessages(ErrorLogger *errorLogger, const Settings * /*settings*/) const override { - CheckUnusedFunctions::unusedFunctionError(errorLogger, emptyString, 0, 0, "funcName"); - } + void getErrorMessages(ErrorLogger */*errorLogger*/, const Settings * /*settings*/) const override {} void runChecks(const Tokenizer & /*tokenizer*/, ErrorLogger * /*errorLogger*/) override {} diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 29a62661314..eb99771a004 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1683,6 +1683,7 @@ void CppCheck::getErrorMessages(ErrorLogger &errorlogger) for (std::list::const_iterator it = Check::instances().cbegin(); it != Check::instances().cend(); ++it) (*it)->getErrorMessages(&errorlogger, &s); + CheckUnusedFunctions::getErrorMessages(&errorlogger); Preprocessor::getErrorMessages(&errorlogger, s); } From 3eee9503af6f8da409fd29126253350581c5bdea Mon Sep 17 00:00:00 2001 From: firewave Date: Sun, 14 Jan 2024 12:35:11 +0100 Subject: [PATCH 2/9] CheckUnusedFunctions: added dedicated `parseTokens()` --- lib/checkunusedfunctions.cpp | 9 +++++++-- lib/checkunusedfunctions.h | 2 ++ lib/cppcheck.cpp | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index f4072d70f5d..f0ba94ff43d 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -370,12 +370,17 @@ void CheckUnusedFunctions::unusedFunctionError(ErrorLogger * const errorLogger, Check::writeToErrorList(errmsg); } -Check::FileInfo *CheckUnusedFunctions::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const +void CheckUnusedFunctions::parseTokens(const Tokenizer *tokenizer, const Settings *settings) { if (!settings->checks.isEnabled(Checks::unusedFunction)) - return nullptr; + return; if (settings->useSingleJob() && settings->buildDir.empty()) instance.parseTokens(*tokenizer, tokenizer->list.getFiles().front().c_str(), settings); +} + +Check::FileInfo *CheckUnusedFunctions::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const +{ + parseTokens(tokenizer, settings); return nullptr; } diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index eedf49252be..177b2a9f855 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -62,6 +62,8 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check { // * What functions are declared void parseTokens(const Tokenizer &tokenizer, const char FileName[], const Settings *settings); + static void parseTokens(const Tokenizer *tokenizer, const Settings *settings); + // Return true if an error is reported. bool check(ErrorLogger * const errorLogger, const Settings& settings) const; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index eb99771a004..8b81f250dee 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -642,7 +642,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string std::ifstream in(filename); tokenizer.list.createTokens(in, filename); } - checkUnusedFunctions.getFileInfo(&tokenizer, &mSettings); + CheckUnusedFunctions::parseTokens(&tokenizer, &mSettings); return EXIT_SUCCESS; } From ca955248b52a1418f0a209d0a1e168893d5a9087 Mon Sep 17 00:00:00 2001 From: firewave Date: Sun, 14 Jan 2024 12:41:21 +0100 Subject: [PATCH 3/9] CheckUnusedFunctions: made `check()` private --- lib/checkunusedfunctions.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index 177b2a9f855..9615fd9a57f 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -48,6 +48,7 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check { friend class TestSingleExecutorBase; friend class TestProcessExecutorBase; friend class TestThreadExecutorBase; + friend class TestUnusedFunctions; public: /** @brief This constructor is used when registering the CheckUnusedFunctions */ @@ -64,9 +65,6 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check { static void parseTokens(const Tokenizer *tokenizer, const Settings *settings); - // Return true if an error is reported. - bool check(ErrorLogger * const errorLogger, const Settings& settings) const; - /** @brief Parse current TU and extract file info */ Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const override; @@ -85,6 +83,9 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check { private: static void clear(); + // Return true if an error is reported. + bool check(ErrorLogger * const errorLogger, const Settings& settings) const; + void getErrorMessages(ErrorLogger */*errorLogger*/, const Settings * /*settings*/) const override {} void runChecks(const Tokenizer & /*tokenizer*/, ErrorLogger * /*errorLogger*/) override {} From 792848306dc11ec5f62b2070c6033d7d4088960e Mon Sep 17 00:00:00 2001 From: firewave Date: Sun, 14 Jan 2024 12:49:56 +0100 Subject: [PATCH 4/9] CheckUnusedFunctions: added dedicated `check()` / avoid ambiguity of `analyseWholeProgram()` --- lib/checkunusedfunctions.cpp | 11 ++++------- lib/checkunusedfunctions.h | 7 +++---- lib/cppcheck.cpp | 8 +++++++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index f0ba94ff43d..ce9ef479140 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -384,14 +384,11 @@ Check::FileInfo *CheckUnusedFunctions::getFileInfo(const Tokenizer *tokenizer, c return nullptr; } -bool CheckUnusedFunctions::analyseWholeProgram(const CTU::FileInfo *ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) +bool CheckUnusedFunctions::check(const Settings& settings, ErrorLogger &errorLogger) { - (void)ctu; - (void)fileInfo; CheckUnusedFunctions dummy(nullptr, &settings, &errorLogger); - dummy. - logChecker("CheckUnusedFunctions::analyseWholeProgram"); // unusedFunctions - return check(&errorLogger, settings); + dummy.logChecker("CheckUnusedFunctions::analyseWholeProgram"); + return instance.check(&errorLogger, settings); } CheckUnusedFunctions::FunctionDecl::FunctionDecl(const Function *f) @@ -421,7 +418,7 @@ namespace { }; } -void CheckUnusedFunctions::analyseWholeProgram(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir) +void CheckUnusedFunctions::analyseWholeProgram2(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir) { std::map decls; std::set calls; diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index 9615fd9a57f..204a8cf66ca 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -68,18 +68,17 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check { /** @brief Parse current TU and extract file info */ Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const override; - /** @brief Analyse all file infos for all TU */ - bool analyseWholeProgram(const CTU::FileInfo *ctu, const std::list &fileInfo, const Settings& settings, ErrorLogger &errorLogger) override; - std::string analyzerInfo() const; /** @brief Combine and analyze all analyzerInfos for all TUs */ - static void analyseWholeProgram(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir); + static void analyseWholeProgram2(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir); static void getErrorMessages(ErrorLogger *errorLogger) { unusedFunctionError(errorLogger, emptyString, 0, 0, "funcName"); } + static bool check(const Settings& settings, ErrorLogger &errorLogger); + private: static void clear(); diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 8b81f250dee..9022cff89d8 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1778,9 +1778,13 @@ bool CppCheck::analyseWholeProgram() ctu.nestedCalls.insert(ctu.nestedCalls.end(), fi2->nestedCalls.cbegin(), fi2->nestedCalls.cend()); } } + // cppcheck-suppress shadowFunction - TODO: fix this for (Check *check : Check::instances()) errors |= check->analyseWholeProgram(&ctu, mFileInfo, mSettings, *this); // TODO: ctu + + errors |= CheckUnusedFunctions::check(mSettings, *this); + return errors && (mExitCode > 0); } @@ -1792,7 +1796,7 @@ void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::list< return; } if (mSettings.checks.isEnabled(Checks::unusedFunction)) - CheckUnusedFunctions::analyseWholeProgram(mSettings, this, buildDir); + CheckUnusedFunctions::analyseWholeProgram2(mSettings, this, buildDir); std::list fileInfoList; CTU::FileInfo ctuFileInfo; @@ -1845,6 +1849,8 @@ void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::list< for (Check *check : Check::instances()) check->analyseWholeProgram(&ctuFileInfo, fileInfoList, mSettings, *this); + CheckUnusedFunctions::check(mSettings, *this); + for (Check::FileInfo *fi : fileInfoList) delete fi; } From 192702a6a11376e3b27c1f65f6aceea0809e7b06 Mon Sep 17 00:00:00 2001 From: firewave Date: Sun, 14 Jan 2024 12:55:44 +0100 Subject: [PATCH 5/9] CheckUnusedFunctions: got rid of unnecessary `getFileInfo()` overload --- lib/checkunusedfunctions.cpp | 6 ------ lib/checkunusedfunctions.h | 3 --- lib/cppcheck.cpp | 2 ++ 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index ce9ef479140..f6c09248c1a 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -378,12 +378,6 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer *tokenizer, const Setting instance.parseTokens(*tokenizer, tokenizer->list.getFiles().front().c_str(), settings); } -Check::FileInfo *CheckUnusedFunctions::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const -{ - parseTokens(tokenizer, settings); - return nullptr; -} - bool CheckUnusedFunctions::check(const Settings& settings, ErrorLogger &errorLogger) { CheckUnusedFunctions dummy(nullptr, &settings, &errorLogger); diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index 204a8cf66ca..7131f0636b2 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -65,9 +65,6 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check { static void parseTokens(const Tokenizer *tokenizer, const Settings *settings); - /** @brief Parse current TU and extract file info */ - Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const override; - std::string analyzerInfo() const; /** @brief Combine and analyze all analyzerInfos for all TUs */ diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 9022cff89d8..4a64df86345 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1137,6 +1137,8 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer) delete fi; } } + + CheckUnusedFunctions::parseTokens(&tokenizer, &mSettings); } #ifdef HAVE_RULES From 908125b6219fe449b5312a4e5513d5cf14e1658e Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 16 Jan 2024 01:48:05 +0100 Subject: [PATCH 6/9] stop pretending `CheckUnusedFunctions` is a real `Check` --- lib/checkunusedfunctions.cpp | 8 ++-- lib/checkunusedfunctions.h | 33 ++------------- lib/cppcheck.cpp | 79 ++++++++++++++++++------------------ test/testunusedfunctions.cpp | 4 +- 4 files changed, 49 insertions(+), 75 deletions(-) diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index f6c09248c1a..80b0724bc08 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -21,6 +21,7 @@ #include "checkunusedfunctions.h" #include "astutils.h" +#include "check.h" #include "errorlogger.h" #include "errortypes.h" #include "library.h" @@ -380,8 +381,9 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer *tokenizer, const Setting bool CheckUnusedFunctions::check(const Settings& settings, ErrorLogger &errorLogger) { - CheckUnusedFunctions dummy(nullptr, &settings, &errorLogger); - dummy.logChecker("CheckUnusedFunctions::analyseWholeProgram"); + // TODO + //CheckUnusedFunctions dummy(nullptr, &settings, &errorLogger); + //dummy.logChecker("CheckUnusedFunctions::analyseWholeProgram"); return instance.check(&errorLogger, settings); } @@ -412,7 +414,7 @@ namespace { }; } -void CheckUnusedFunctions::analyseWholeProgram2(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir) +void CheckUnusedFunctions::analyseWholeProgram(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir) { std::map decls; std::set calls; diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index 7131f0636b2..1e3d5e8bab4 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -22,7 +22,6 @@ #define checkunusedfunctionsH //--------------------------------------------------------------------------- -#include "check.h" #include "config.h" #include @@ -35,15 +34,10 @@ class Function; class Settings; class Tokenizer; -namespace CTU { - class FileInfo; -} - -/// @addtogroup Checks /** @brief Check for functions never called */ /// @{ -class CPPCHECKLIB CheckUnusedFunctions : public Check { +class CPPCHECKLIB CheckUnusedFunctions { friend class TestSuppressions; friend class TestSingleExecutorBase; friend class TestProcessExecutorBase; @@ -51,12 +45,7 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check { friend class TestUnusedFunctions; public: - /** @brief This constructor is used when registering the CheckUnusedFunctions */ - CheckUnusedFunctions() : Check(myName()) {} - - /** @brief This constructor is used when running checks. */ - CheckUnusedFunctions(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger) {} + CheckUnusedFunctions() = default; // Parse current tokens and determine.. // * Check what functions are used @@ -67,8 +56,7 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check { std::string analyzerInfo() const; - /** @brief Combine and analyze all analyzerInfos for all TUs */ - static void analyseWholeProgram2(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir); + static void analyseWholeProgram(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir); static void getErrorMessages(ErrorLogger *errorLogger) { unusedFunctionError(errorLogger, emptyString, 0, 0, "funcName"); @@ -82,25 +70,10 @@ class CPPCHECKLIB CheckUnusedFunctions : public Check { // Return true if an error is reported. bool check(ErrorLogger * const errorLogger, const Settings& settings) const; - void getErrorMessages(ErrorLogger */*errorLogger*/, const Settings * /*settings*/) const override {} - - void runChecks(const Tokenizer & /*tokenizer*/, ErrorLogger * /*errorLogger*/) override {} - - /** - * Dummy implementation, just to provide error for --errorlist - */ static void unusedFunctionError(ErrorLogger * const errorLogger, const std::string &filename, unsigned int fileIndex, unsigned int lineNumber, const std::string &funcname); - static std::string myName() { - return "Unused functions"; - } - - std::string classInfo() const override { - return "Check for functions that are never called\n"; - } - struct CPPCHECKLIB FunctionUsage { std::string filename; unsigned int lineNumber{}; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 4a64df86345..346862ea27e 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -631,7 +631,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string mPlistFile.close(); } - CheckUnusedFunctions checkUnusedFunctions(nullptr, nullptr, nullptr); + CheckUnusedFunctions checkUnusedFunctions; try { if (mSettings.library.markupFile(filename)) { @@ -1076,39 +1076,39 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer) const char* unusedFunctionOnly = std::getenv("UNUSEDFUNCTION_ONLY"); const bool doUnusedFunctionOnly = unusedFunctionOnly && (std::strcmp(unusedFunctionOnly, "1") == 0); - const std::time_t maxTime = mSettings.checksMaxTime > 0 ? std::time(nullptr) + mSettings.checksMaxTime : 0; + if (!doUnusedFunctionOnly) { + const std::time_t maxTime = mSettings.checksMaxTime > 0 ? std::time(nullptr) + mSettings.checksMaxTime : 0; - // call all "runChecks" in all registered Check classes - // cppcheck-suppress shadowFunction - TODO: fix this - for (Check *check : Check::instances()) { - if (Settings::terminated()) - return; - - if (maxTime > 0 && std::time(nullptr) > maxTime) { - if (mSettings.debugwarnings) { - ErrorMessage::FileLocation loc; - loc.setfile(tokenizer.list.getFiles()[0]); - ErrorMessage errmsg({std::move(loc)}, - emptyString, - Severity::debug, - "Checks maximum time exceeded", - "checksMaxTime", - Certainty::normal); - reportErr(errmsg); + // call all "runChecks" in all registered Check classes + // cppcheck-suppress shadowFunction - TODO: fix this + for (Check *check : Check::instances()) { + if (Settings::terminated()) + return; + + if (maxTime > 0 && std::time(nullptr) > maxTime) { + if (mSettings.debugwarnings) { + ErrorMessage::FileLocation loc; + loc.setfile(tokenizer.list.getFiles()[0]); + ErrorMessage errmsg({std::move(loc)}, + emptyString, + Severity::debug, + "Checks maximum time exceeded", + "checksMaxTime", + Certainty::normal); + reportErr(errmsg); + } + return; } - return; - } - if (doUnusedFunctionOnly && dynamic_cast(check) == nullptr) - continue; - - Timer timerRunChecks(check->name() + "::runChecks", mSettings.showtime, &s_timerResults); - check->runChecks(tokenizer, this); + Timer timerRunChecks(check->name() + "::runChecks", mSettings.showtime, &s_timerResults); + check->runChecks(tokenizer, this); + } } - if (mSettings.clang) + if (mSettings.clang) { // TODO: Use CTU for Clang analysis return; + } if (mSettings.useSingleJob() || !mSettings.buildDir.empty()) { @@ -1123,18 +1123,17 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer) delete fi1; } - // cppcheck-suppress shadowFunction - TODO: fix this - for (const Check *check : Check::instances()) { - if (doUnusedFunctionOnly && dynamic_cast(check) == nullptr) - continue; - - if (Check::FileInfo * const fi = check->getFileInfo(&tokenizer, &mSettings)) { - if (!mSettings.buildDir.empty()) - mAnalyzerInformation.setFileInfo(check->name(), fi->toString()); - if (mSettings.useSingleJob()) - mFileInfo.push_back(fi); - else - delete fi; + if (!doUnusedFunctionOnly) { + // cppcheck-suppress shadowFunction - TODO: fix this + for (const Check *check : Check::instances()) { + if (Check::FileInfo * const fi = check->getFileInfo(&tokenizer, &mSettings)) { + if (!mSettings.buildDir.empty()) + mAnalyzerInformation.setFileInfo(check->name(), fi->toString()); + if (mSettings.useSingleJob()) + mFileInfo.push_back(fi); + else + delete fi; + } } } @@ -1798,7 +1797,7 @@ void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::list< return; } if (mSettings.checks.isEnabled(Checks::unusedFunction)) - CheckUnusedFunctions::analyseWholeProgram2(mSettings, this, buildDir); + CheckUnusedFunctions::analyseWholeProgram(mSettings, this, buildDir); std::list fileInfoList; CTU::FileInfo ctuFileInfo; diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index 04f88c39dac..a619216a821 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -95,7 +95,7 @@ class TestUnusedFunctions : public TestFixture { ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); // Check for unused functions.. - CheckUnusedFunctions checkUnusedFunctions(&tokenizer, &settings1, this); + CheckUnusedFunctions checkUnusedFunctions; checkUnusedFunctions.parseTokens(tokenizer, "someFile.c", &settings1); // check() returns error if and only if errout is not empty. if ((checkUnusedFunctions.check)(this, settings1)) { @@ -538,7 +538,7 @@ class TestUnusedFunctions : public TestFixture { void multipleFiles() { Tokenizer tokenizer(settings, this); - CheckUnusedFunctions c(&tokenizer, &settings, nullptr); + CheckUnusedFunctions c; // Clear the error buffer.. errout.str(""); From 5131e7e6adde55186d1884f4058ebfc7c92d9dcc Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 16 Jan 2024 02:06:56 +0100 Subject: [PATCH 7/9] pass references into `CheckUnusedFunctions` --- Makefile | 2 +- lib/checkunusedfunctions.cpp | 48 +++++++++++++++++------------------- lib/checkunusedfunctions.h | 12 ++++----- lib/cppcheck.cpp | 10 ++++---- test/testunusedfunctions.cpp | 8 +++--- 5 files changed, 38 insertions(+), 42 deletions(-) diff --git a/Makefile b/Makefile index a4d33f18c67..fa42518dda1 100644 --- a/Makefile +++ b/Makefile @@ -551,7 +551,7 @@ $(libcppdir)/checktype.o: lib/checktype.cpp lib/addoninfo.h lib/check.h lib/chec $(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checknullpointer.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp $(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index 80b0724bc08..5f06b46e82f 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -21,7 +21,6 @@ #include "checkunusedfunctions.h" #include "astutils.h" -#include "check.h" #include "errorlogger.h" #include "errortypes.h" #include "library.h" @@ -75,9 +74,9 @@ void CheckUnusedFunctions::clear() instance.mFunctionCalls.clear(); } -void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char FileName[], const Settings *settings) +void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char FileName[], const Settings &settings) { - const bool doMarkup = settings->library.markupFile(FileName); + const bool doMarkup = settings.library.markupFile(FileName); // Function declarations.. if (!doMarkup) { @@ -126,8 +125,8 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi lambdaEndToken = findLambdaEndToken(tok); // parsing of library code to find called functions - if (settings->library.isexecutableblock(FileName, tok->str())) { - const Token * markupVarToken = tok->tokAt(settings->library.blockstartoffset(FileName)); + if (settings.library.isexecutableblock(FileName, tok->str())) { + const Token * markupVarToken = tok->tokAt(settings.library.blockstartoffset(FileName)); // not found if (!markupVarToken) continue; @@ -135,12 +134,12 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi bool start = true; // find all function calls in library code (starts with '(', not if or while etc) while ((scope || start) && markupVarToken) { - if (markupVarToken->str() == settings->library.blockstart(FileName)) { + if (markupVarToken->str() == settings.library.blockstart(FileName)) { scope++; start = false; - } else if (markupVarToken->str() == settings->library.blockend(FileName)) + } else if (markupVarToken->str() == settings.library.blockend(FileName)) scope--; - else if (!settings->library.iskeyword(FileName, markupVarToken->str())) { + else if (!settings.library.iskeyword(FileName, markupVarToken->str())) { mFunctionCalls.insert(markupVarToken->str()); if (mFunctions.find(markupVarToken->str()) != mFunctions.end()) mFunctions[markupVarToken->str()].usedOtherFile = true; @@ -158,10 +157,10 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi } if (!doMarkup // only check source files - && settings->library.isexporter(tok->str()) && tok->next() != nullptr) { + && settings.library.isexporter(tok->str()) && tok->next() != nullptr) { const Token * propToken = tok->next(); while (propToken && propToken->str() != ")") { - if (settings->library.isexportedprefix(tok->str(), propToken->str())) { + if (settings.library.isexportedprefix(tok->str(), propToken->str())) { const Token* nextPropToken = propToken->next(); const std::string& value = nextPropToken->str(); if (mFunctions.find(value) != mFunctions.end()) { @@ -169,7 +168,7 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi } mFunctionCalls.insert(value); } - if (settings->library.isexportedsuffix(tok->str(), propToken->str())) { + if (settings.library.isexportedsuffix(tok->str(), propToken->str())) { const Token* prevPropToken = propToken->previous(); const std::string& value = prevPropToken->str(); if (value != ")" && mFunctions.find(value) != mFunctions.end()) { @@ -181,7 +180,7 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi } } - if (doMarkup && settings->library.isimporter(FileName, tok->str()) && tok->next()) { + if (doMarkup && settings.library.isimporter(FileName, tok->str()) && tok->next()) { const Token * propToken = tok->next(); if (propToken->next()) { propToken = propToken->next(); @@ -197,8 +196,8 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi } } - if (settings->library.isreflection(tok->str())) { - const int argIndex = settings->library.reflectionArgument(tok->str()); + if (settings.library.isreflection(tok->str())) { + const int argIndex = settings.library.reflectionArgument(tok->str()); if (argIndex >= 0) { const Token * funcToken = tok->next(); int index = 0; @@ -320,7 +319,7 @@ static bool isOperatorFunction(const std::string & funcName) return std::find(additionalOperators.cbegin(), additionalOperators.cend(), funcName.substr(operatorPrefix.length())) != additionalOperators.cend(); } -bool CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings& settings) const +bool CheckUnusedFunctions::check(ErrorLogger& errorLogger, const Settings& settings) const { using ErrorParams = std::tuple; std::vector errors; // ensure well-defined order @@ -354,7 +353,7 @@ bool CheckUnusedFunctions::check(ErrorLogger * const errorLogger, const Settings return !errors.empty(); } -void CheckUnusedFunctions::unusedFunctionError(ErrorLogger * const errorLogger, +void CheckUnusedFunctions::unusedFunctionError(ErrorLogger& errorLogger, const std::string &filename, unsigned int fileIndex, unsigned int lineNumber, const std::string &funcname) { @@ -365,18 +364,15 @@ void CheckUnusedFunctions::unusedFunctionError(ErrorLogger * const errorLogger, } const ErrorMessage errmsg(std::move(locationList), emptyString, Severity::style, "$symbol:" + funcname + "\nThe function '$symbol' is never used.", "unusedFunction", CWE561, Certainty::normal); - if (errorLogger) - errorLogger->reportErr(errmsg); - else - Check::writeToErrorList(errmsg); + errorLogger.reportErr(errmsg); } -void CheckUnusedFunctions::parseTokens(const Tokenizer *tokenizer, const Settings *settings) +void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Settings &settings) { - if (!settings->checks.isEnabled(Checks::unusedFunction)) + if (!settings.checks.isEnabled(Checks::unusedFunction)) return; - if (settings->useSingleJob() && settings->buildDir.empty()) - instance.parseTokens(*tokenizer, tokenizer->list.getFiles().front().c_str(), settings); + if (settings.useSingleJob() && settings.buildDir.empty()) + instance.parseTokens(tokenizer, tokenizer.list.getFiles().front().c_str(), settings); } bool CheckUnusedFunctions::check(const Settings& settings, ErrorLogger &errorLogger) @@ -384,7 +380,7 @@ bool CheckUnusedFunctions::check(const Settings& settings, ErrorLogger &errorLog // TODO //CheckUnusedFunctions dummy(nullptr, &settings, &errorLogger); //dummy.logChecker("CheckUnusedFunctions::analyseWholeProgram"); - return instance.check(&errorLogger, settings); + return instance.check(errorLogger, settings); } CheckUnusedFunctions::FunctionDecl::FunctionDecl(const Function *f) @@ -414,7 +410,7 @@ namespace { }; } -void CheckUnusedFunctions::analyseWholeProgram(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir) +void CheckUnusedFunctions::analyseWholeProgram(const Settings &settings, ErrorLogger &errorLogger, const std::string &buildDir) { std::map decls; std::set calls; diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index 1e3d5e8bab4..6db37f95aeb 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -50,15 +50,15 @@ class CPPCHECKLIB CheckUnusedFunctions { // Parse current tokens and determine.. // * Check what functions are used // * What functions are declared - void parseTokens(const Tokenizer &tokenizer, const char FileName[], const Settings *settings); + void parseTokens(const Tokenizer &tokenizer, const char FileName[], const Settings &settings); - static void parseTokens(const Tokenizer *tokenizer, const Settings *settings); + static void parseTokens(const Tokenizer &tokenizer, const Settings &settings); std::string analyzerInfo() const; - static void analyseWholeProgram(const Settings &settings, ErrorLogger * const errorLogger, const std::string &buildDir); + static void analyseWholeProgram(const Settings &settings, ErrorLogger& errorLogger, const std::string &buildDir); - static void getErrorMessages(ErrorLogger *errorLogger) { + static void getErrorMessages(ErrorLogger &errorLogger) { unusedFunctionError(errorLogger, emptyString, 0, 0, "funcName"); } @@ -68,9 +68,9 @@ class CPPCHECKLIB CheckUnusedFunctions { static void clear(); // Return true if an error is reported. - bool check(ErrorLogger * const errorLogger, const Settings& settings) const; + bool check(ErrorLogger& errorLogger, const Settings& settings) const; - static void unusedFunctionError(ErrorLogger * const errorLogger, + static void unusedFunctionError(ErrorLogger& errorLogger, const std::string &filename, unsigned int fileIndex, unsigned int lineNumber, const std::string &funcname); diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 346862ea27e..ddf9f4c49d0 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -642,7 +642,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string std::ifstream in(filename); tokenizer.list.createTokens(in, filename); } - CheckUnusedFunctions::parseTokens(&tokenizer, &mSettings); + CheckUnusedFunctions::parseTokens(tokenizer, mSettings); return EXIT_SUCCESS; } @@ -935,7 +935,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string // Analyze info.. if (!mSettings.buildDir.empty()) - checkUnusedFunctions.parseTokens(tokenizer, filename.c_str(), &mSettings); + checkUnusedFunctions.parseTokens(tokenizer, filename.c_str(), mSettings); #ifdef HAVE_RULES // handling of "simple" rules has been removed. @@ -1137,7 +1137,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer) } } - CheckUnusedFunctions::parseTokens(&tokenizer, &mSettings); + CheckUnusedFunctions::parseTokens(tokenizer, mSettings); } #ifdef HAVE_RULES @@ -1684,7 +1684,7 @@ void CppCheck::getErrorMessages(ErrorLogger &errorlogger) for (std::list::const_iterator it = Check::instances().cbegin(); it != Check::instances().cend(); ++it) (*it)->getErrorMessages(&errorlogger, &s); - CheckUnusedFunctions::getErrorMessages(&errorlogger); + CheckUnusedFunctions::getErrorMessages(errorlogger); Preprocessor::getErrorMessages(&errorlogger, s); } @@ -1797,7 +1797,7 @@ void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::list< return; } if (mSettings.checks.isEnabled(Checks::unusedFunction)) - CheckUnusedFunctions::analyseWholeProgram(mSettings, this, buildDir); + CheckUnusedFunctions::analyseWholeProgram(mSettings, *this, buildDir); std::list fileInfoList; CTU::FileInfo ctuFileInfo; diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index a619216a821..d5235a7be93 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -96,9 +96,9 @@ class TestUnusedFunctions : public TestFixture { // Check for unused functions.. CheckUnusedFunctions checkUnusedFunctions; - checkUnusedFunctions.parseTokens(tokenizer, "someFile.c", &settings1); + checkUnusedFunctions.parseTokens(tokenizer, "someFile.c", settings1); // check() returns error if and only if errout is not empty. - if ((checkUnusedFunctions.check)(this, settings1)) { + if ((checkUnusedFunctions.check)(*this, settings1)) { ASSERT(!errout.str().empty()); } else { ASSERT_EQUALS("", errout.str()); @@ -556,11 +556,11 @@ class TestUnusedFunctions : public TestFixture { std::istringstream istr(code); ASSERT(tokenizer2.tokenize(istr, fname.str().c_str())); - c.parseTokens(tokenizer2, "someFile.c", &settings); + c.parseTokens(tokenizer2, "someFile.c", settings); } // Check for unused functions.. - (c.check)(this, settings); + (c.check)(*this, settings); ASSERT_EQUALS("[test1.cpp:1]: (style) The function 'f' is never used.\n", errout.str()); } From dc8127f04594bd60b5e1801e7ff2163833513c1e Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 16 Jan 2024 02:14:42 +0100 Subject: [PATCH 8/9] CheckUnusedFunctions: re-added `logChecker` message --- lib/checkunusedfunctions.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index 5f06b46e82f..a56a448f82c 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -375,11 +375,15 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Setting instance.parseTokens(tokenizer, tokenizer.list.getFiles().front().c_str(), settings); } +#define logChecker(id) \ + do { \ + const ErrorMessage errmsg({}, nullptr, Severity::internal, "logChecker", id, CWE(0U), Certainty::normal); \ + errorLogger.reportErr(errmsg); \ + } while (false) + bool CheckUnusedFunctions::check(const Settings& settings, ErrorLogger &errorLogger) { - // TODO - //CheckUnusedFunctions dummy(nullptr, &settings, &errorLogger); - //dummy.logChecker("CheckUnusedFunctions::analyseWholeProgram"); + logChecker("CheckUnusedFunctions::check"); // unusedFunction return instance.check(errorLogger, settings); } From b347ca13ec12926c48a89c2def9489ff13c4ff26 Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 12 Feb 2024 01:54:51 +0100 Subject: [PATCH 9/9] checkunusedfunctions.cpp: fixed `premium-misra-cpp-2008-16-0-6` selfcheck warning --- lib/checkunusedfunctions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index a56a448f82c..3c707f4dcb7 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -377,7 +377,7 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const Setting #define logChecker(id) \ do { \ - const ErrorMessage errmsg({}, nullptr, Severity::internal, "logChecker", id, CWE(0U), Certainty::normal); \ + const ErrorMessage errmsg({}, nullptr, Severity::internal, "logChecker", (id), CWE(0U), Certainty::normal); \ errorLogger.reportErr(errmsg); \ } while (false)