From 4f0c4326a939898304907b8fe6fb6cc2215b8d95 Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 20 Jan 2025 04:48:35 +0100 Subject: [PATCH] fixed #8437 - got rid of single global `TimerResults` instance --- Makefile | 2 +- cli/cppcheckexecutor.cpp | 9 +++++---- cli/executor.cpp | 4 ++-- cli/executor.h | 4 +++- cli/processexecutor.cpp | 10 ++++----- cli/processexecutor.h | 3 ++- cli/singleexecutor.cpp | 8 ++++---- cli/singleexecutor.h | 3 ++- cli/threadexecutor.cpp | 26 ++++++++++++------------ cli/threadexecutor.h | 3 ++- democlient/democlient.cpp | 2 +- gui/checkthread.cpp | 2 +- gui/mainwindow.cpp | 2 +- lib/cppcheck.cpp | 39 +++++++++++++----------------------- lib/cppcheck.h | 8 +++----- lib/timer.h | 2 +- oss-fuzz/main.cpp | 2 +- test/fixture.cpp | 2 -- test/testcppcheck.cpp | 30 +++++++++++++-------------- test/testexecutor.cpp | 2 +- test/testprocessexecutor.cpp | 3 ++- test/testsingleexecutor.cpp | 5 +++-- test/testsuppressions.cpp | 13 ++++++------ test/testthreadexecutor.cpp | 3 ++- 24 files changed, 90 insertions(+), 97 deletions(-) diff --git a/Makefile b/Makefile index 3fef3103d96..d5e3f74f6d1 100644 --- a/Makefile +++ b/Makefile @@ -718,7 +718,7 @@ cli/stacktrace.o: cli/stacktrace.cpp cli/stacktrace.h lib/config.h lib/utils.h cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/threadexecutor.cpp -test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h +test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/helpers.h diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index c5daf5079e9..a16f76183c0 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -382,6 +382,7 @@ bool CppCheckExecutor::reportUnmatchedSuppressions(const Settings &settings, con int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& supprs) const { StdLogger stdLogger(settings); + TimerResults timerResults; if (settings.reportProgress >= 0) stdLogger.resetLatestProgressOutputTime(); @@ -402,23 +403,23 @@ int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& sup if (!settings.checkersReportFilename.empty()) std::remove(settings.checkersReportFilename.c_str()); - CppCheck cppcheck(settings, supprs, stdLogger, true, executeCommand); + CppCheck cppcheck(settings, supprs, stdLogger, &timerResults, true, executeCommand); unsigned int returnValue = 0; if (settings.useSingleJob()) { // Single process - SingleExecutor executor(cppcheck, mFiles, mFileSettings, settings, supprs, stdLogger); + SingleExecutor executor(cppcheck, mFiles, mFileSettings, settings, supprs, stdLogger, &timerResults); returnValue = executor.check(); } else { #if defined(HAS_THREADING_MODEL_THREAD) if (settings.executor == Settings::ExecutorType::Thread) { - ThreadExecutor executor(mFiles, mFileSettings, settings, supprs, stdLogger, CppCheckExecutor::executeCommand); + ThreadExecutor executor(mFiles, mFileSettings, settings, supprs, stdLogger, &timerResults, CppCheckExecutor::executeCommand); returnValue = executor.check(); } #endif #if defined(HAS_THREADING_MODEL_FORK) if (settings.executor == Settings::ExecutorType::Process) { - ProcessExecutor executor(mFiles, mFileSettings, settings, supprs, stdLogger, CppCheckExecutor::executeCommand); + ProcessExecutor executor(mFiles, mFileSettings, settings, supprs, stdLogger, &timerResults, CppCheckExecutor::executeCommand); returnValue = executor.check(); } #endif diff --git a/cli/executor.cpp b/cli/executor.cpp index 8ef1de84a90..c9c0c73c56e 100644 --- a/cli/executor.cpp +++ b/cli/executor.cpp @@ -30,8 +30,8 @@ struct FileSettings; -Executor::Executor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger) - : mFiles(files), mFileSettings(fileSettings), mSettings(settings), mSuppressions(suppressions), mErrorLogger(errorLogger) +Executor::Executor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, TimerResults* timerResults) + : mFiles(files), mFileSettings(fileSettings), mSettings(settings), mSuppressions(suppressions), mErrorLogger(errorLogger), mTimerResults(timerResults) { // the two inputs may only be used exclusively assert(!(!files.empty() && !fileSettings.empty())); diff --git a/cli/executor.h b/cli/executor.h index 3f24b1c9b00..d5a20fd4527 100644 --- a/cli/executor.h +++ b/cli/executor.h @@ -31,6 +31,7 @@ class ErrorMessage; struct Suppressions; struct FileSettings; class FileWithDetails; +class TimerResults; /// @addtogroup CLI /// @{ @@ -41,7 +42,7 @@ class FileWithDetails; */ class Executor { public: - Executor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger); + Executor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, TimerResults* timerResults); virtual ~Executor() = default; Executor(const Executor &) = delete; @@ -72,6 +73,7 @@ class Executor { const Settings &mSettings; Suppressions &mSuppressions; ErrorLogger &mErrorLogger; + TimerResults *mTimerResults; private: std::mutex mErrorListSync; diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index d0ca09ffec1..963818ecfb2 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -68,8 +68,8 @@ enum class Color : std::uint8_t; using std::memset; -ProcessExecutor::ProcessExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand) - : Executor(files, fileSettings, settings, suppressions, errorLogger) +ProcessExecutor::ProcessExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, TimerResults* timerResults, CppCheck::ExecuteCmdFn executeCommand) + : Executor(files, fileSettings, settings, suppressions, errorLogger, timerResults) , mExecuteCommand(std::move(executeCommand)) { assert(mSettings.jobs > 1); @@ -344,7 +344,7 @@ unsigned int ProcessExecutor::check() close(pipes[0]); PipeWriter pipewriter(pipes[1]); - CppCheck fileChecker(mSettings, mSuppressions, pipewriter, false, mExecuteCommand); + CppCheck fileChecker(mSettings, mSuppressions, pipewriter, mTimerResults, false, mExecuteCommand); unsigned int resultOfCheck = 0; if (iFileSettings != mFileSettings.end()) { @@ -450,8 +450,8 @@ unsigned int ProcessExecutor::check() } // TODO: wee need to get the timing information from the subprocess - if (mSettings.showtime == ShowTime::SUMMARY || mSettings.showtime == ShowTime::TOP5_SUMMARY) - CppCheck::printTimerResults(mSettings.showtime); + if (mTimerResults && (mSettings.showtime == ShowTime::SUMMARY || mSettings.showtime == ShowTime::TOP5_SUMMARY)) + mTimerResults->showResults(mSettings.showtime); return result; } diff --git a/cli/processexecutor.h b/cli/processexecutor.h index 9ed14e6af96..f813b1893e5 100644 --- a/cli/processexecutor.h +++ b/cli/processexecutor.h @@ -35,6 +35,7 @@ class ErrorLogger; struct Suppressions; struct FileSettings; class FileWithDetails; +class TimerResults; /// @addtogroup CLI /// @{ @@ -45,7 +46,7 @@ class FileWithDetails; */ class ProcessExecutor : public Executor { public: - ProcessExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand); + ProcessExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, TimerResults* timerResults, CppCheck::ExecuteCmdFn executeCommand); ProcessExecutor(const ProcessExecutor &) = delete; ProcessExecutor& operator=(const ProcessExecutor &) = delete; diff --git a/cli/singleexecutor.cpp b/cli/singleexecutor.cpp index 2dec1b6ad14..9da1645a6a4 100644 --- a/cli/singleexecutor.cpp +++ b/cli/singleexecutor.cpp @@ -30,8 +30,8 @@ class ErrorLogger; -SingleExecutor::SingleExecutor(CppCheck &cppcheck, const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger) - : Executor(files, fileSettings, settings, suppressions, errorLogger) +SingleExecutor::SingleExecutor(CppCheck &cppcheck, const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, TimerResults* timerResults) + : Executor(files, fileSettings, settings, suppressions, errorLogger, timerResults) , mCppcheck(cppcheck) { assert(mSettings.jobs == 1); @@ -71,8 +71,8 @@ unsigned int SingleExecutor::check() if (mCppcheck.analyseWholeProgram()) result++; - if (mSettings.showtime == ShowTime::SUMMARY || mSettings.showtime == ShowTime::TOP5_SUMMARY) - CppCheck::printTimerResults(mSettings.showtime); + if (mTimerResults && (mSettings.showtime == ShowTime::SUMMARY || mSettings.showtime == ShowTime::TOP5_SUMMARY)) + mTimerResults->showResults(mSettings.showtime); return result; } diff --git a/cli/singleexecutor.h b/cli/singleexecutor.h index c2294a2e467..b6cae501214 100644 --- a/cli/singleexecutor.h +++ b/cli/singleexecutor.h @@ -29,11 +29,12 @@ class CppCheck; struct Suppressions; struct FileSettings; class FileWithDetails; +class TimerResults; class SingleExecutor : public Executor { public: - SingleExecutor(CppCheck &cppcheck, const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger); + SingleExecutor(CppCheck &cppcheck, const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, TimerResults* timerResults); SingleExecutor(const SingleExecutor &) = delete; SingleExecutor& operator=(const SingleExecutor &) = delete; diff --git a/cli/threadexecutor.cpp b/cli/threadexecutor.cpp index 4b75f423f23..bdf1fb6f2e0 100644 --- a/cli/threadexecutor.cpp +++ b/cli/threadexecutor.cpp @@ -40,8 +40,8 @@ #include #include -ThreadExecutor::ThreadExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand) - : Executor(files, fileSettings, settings, suppressions, errorLogger) +ThreadExecutor::ThreadExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, TimerResults* timerResults, CppCheck::ExecuteCmdFn executeCommand) + : Executor(files, fileSettings, settings, suppressions, errorLogger, timerResults) , mExecuteCommand(std::move(executeCommand)) { assert(mSettings.jobs > 1); @@ -87,8 +87,8 @@ class SyncLogForwarder : public ErrorLogger class ThreadData { public: - ThreadData(ThreadExecutor &threadExecutor, ErrorLogger &errorLogger, const Settings &settings, Suppressions& supprs, const std::list &files, const std::list &fileSettings, CppCheck::ExecuteCmdFn executeCommand) - : mFiles(files), mFileSettings(fileSettings), mSettings(settings), mSuppressions(supprs), mExecuteCommand(std::move(executeCommand)), logForwarder(threadExecutor, errorLogger) + ThreadData(ThreadExecutor &threadExecutor, ErrorLogger &errorLogger, TimerResults *timerResults, const Settings &settings, Suppressions& supprs, const std::list &files, const std::list &fileSettings, CppCheck::ExecuteCmdFn executeCommand) + : mFiles(files), mFileSettings(fileSettings), mTimerResults(timerResults), mSettings(settings), mSuppressions(supprs), mExecuteCommand(std::move(executeCommand)), mLogForwarder(threadExecutor, errorLogger) { mItNextFile = mFiles.begin(); mItNextFileSettings = mFileSettings.begin(); @@ -119,8 +119,8 @@ class ThreadData return false; } - unsigned int check(ErrorLogger &errorLogger, const FileWithDetails *file, const FileSettings *fs) const { - CppCheck fileChecker(mSettings, mSuppressions, errorLogger, false, mExecuteCommand); + unsigned int check(const FileWithDetails *file, const FileSettings *fs) { + CppCheck fileChecker(mSettings, mSuppressions, mLogForwarder, mTimerResults, false, mExecuteCommand); unsigned int result; if (fs) { @@ -155,7 +155,7 @@ class ThreadData mProcessedSize += fileSize; mProcessedFiles++; if (!mSettings.quiet) - logForwarder.reportStatus(mProcessedFiles, mTotalFiles, mProcessedSize, mTotalFileSize); + mLogForwarder.reportStatus(mProcessedFiles, mTotalFiles, mProcessedSize, mTotalFileSize); } private: @@ -170,12 +170,12 @@ class ThreadData std::size_t mTotalFileSize{}; std::mutex mFileSync; + TimerResults *mTimerResults; const Settings &mSettings; Suppressions &mSuppressions; CppCheck::ExecuteCmdFn mExecuteCommand; -public: - SyncLogForwarder logForwarder; + SyncLogForwarder mLogForwarder; }; static unsigned int STDCALL threadProc(ThreadData *data) @@ -187,7 +187,7 @@ static unsigned int STDCALL threadProc(ThreadData *data) std::size_t fileSize; while (data->next(file, fs, fileSize)) { - result += data->check(data->logForwarder, file, fs); + result += data->check(file, fs); data->status(fileSize); } @@ -200,7 +200,7 @@ unsigned int ThreadExecutor::check() std::vector> threadFutures; threadFutures.reserve(mSettings.jobs); - ThreadData data(*this, mErrorLogger, mSettings, mSuppressions, mFiles, mFileSettings, mExecuteCommand); + ThreadData data(*this, mErrorLogger, mTimerResults, mSettings, mSuppressions, mFiles, mFileSettings, mExecuteCommand); for (unsigned int i = 0; i < mSettings.jobs; ++i) { try { @@ -216,8 +216,8 @@ unsigned int ThreadExecutor::check() return v + f.get(); }); - if (mSettings.showtime == ShowTime::SUMMARY || mSettings.showtime == ShowTime::TOP5_SUMMARY) - CppCheck::printTimerResults(mSettings.showtime); + if (mTimerResults && (mSettings.showtime == ShowTime::SUMMARY || mSettings.showtime == ShowTime::TOP5_SUMMARY)) + mTimerResults->showResults(mSettings.showtime); return result; } diff --git a/cli/threadexecutor.h b/cli/threadexecutor.h index 1e6001347d3..e827969037c 100644 --- a/cli/threadexecutor.h +++ b/cli/threadexecutor.h @@ -33,6 +33,7 @@ class ErrorLogger; struct Suppressions; struct FileSettings; class FileWithDetails; +class TimerResults; /// @addtogroup CLI /// @{ @@ -45,7 +46,7 @@ class ThreadExecutor : public Executor { friend class SyncLogForwarder; public: - ThreadExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand); + ThreadExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, TimerResults* timerResults, CppCheck::ExecuteCmdFn executeCommand); ThreadExecutor(const ThreadExecutor &) = delete; ThreadExecutor& operator=(const ThreadExecutor &) = delete; diff --git a/democlient/democlient.cpp b/democlient/democlient.cpp index e45baf51cbd..177aff28b71 100644 --- a/democlient/democlient.cpp +++ b/democlient/democlient.cpp @@ -63,7 +63,7 @@ class CppcheckExecutor : public ErrorLogger { public: CppcheckExecutor(const Settings& settings) : stoptime(std::time(nullptr)+2U) - , cppcheck(settings, supprs, *this, false, nullptr) + , cppcheck(settings, supprs, *this, nullptr, false, nullptr) {} void run(const char* code) { diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 090b698a6e7..8f042068ee9 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -128,7 +128,7 @@ void CheckThread::run() { mState = Running; - CppCheck cppcheck(mSettings, *mSuppressions, mResult, true, executeCommand); + CppCheck cppcheck(mSettings, *mSuppressions, mResult, nullptr, true, executeCommand); if (!mFiles.empty() || mAnalyseWholeProgram) { mAnalyseWholeProgram = false; diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 6926183974b..2d71ef5e7c6 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -728,7 +728,7 @@ void MainWindow::analyzeCode(const QString& code, const QString& filename) mUI->mResults, SLOT(debugError(ErrorItem))); // Create CppCheck instance - CppCheck cppcheck(checkSettings, supprs, result, true, nullptr); + CppCheck cppcheck(checkSettings, supprs, result, nullptr, true, nullptr); // Check checkLockDownUI(); diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 1b8cc52d86b..399eb6d3d6e 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -80,8 +80,6 @@ static constexpr char ExtraVersion[] = ""; static constexpr char FILELIST[] = "cppcheck-addon-ctu-file-list"; -static TimerResults s_timerResults; - // CWE ids used static const CWE CWE398(398U); // Indicator of Poor Code Quality @@ -534,6 +532,7 @@ static std::string getDefinesFlags(const std::string &semicolonSeparatedString) CppCheck::CppCheck(const Settings& settings, Suppressions& supprs, ErrorLogger &errorLogger, + TimerResults *timerResults, bool useGlobalSuppressions, ExecuteCmdFn executeCommand) : mSettings(settings) @@ -541,6 +540,7 @@ CppCheck::CppCheck(const Settings& settings, , mLogger(new CppCheckLogger(errorLogger, mSettings, mSuppressions, useGlobalSuppressions)) , mErrorLogger(*mLogger) , mErrorLoggerDirect(errorLogger) + , mTimerResults(timerResults) , mUseGlobalSuppressions(useGlobalSuppressions) , mExecuteCommand(std::move(executeCommand)) {} @@ -740,7 +740,7 @@ unsigned int CppCheck::checkClang(const FileWithDetails &file, int fileIndex) const_cast(*tokenizer.getSymbolDatabase()), mErrorLogger, mSettings, - &s_timerResults); + mTimerResults); tokenizer.printDebugOutput(std::cout); checkNormalTokens(tokenizer, nullptr, ""); // TODO: provide analyzer information @@ -829,7 +829,7 @@ unsigned int CppCheck::check(const FileSettings &fs) if (mSettings.clang) { tempSettings.includePaths.insert(tempSettings.includePaths.end(), fs.systemIncludePaths.cbegin(), fs.systemIncludePaths.cend()); // need to pass the externally provided ErrorLogger instead of our internal wrapper - CppCheck temp(tempSettings, mSuppressions, mErrorLoggerDirect, mUseGlobalSuppressions, mExecuteCommand); + CppCheck temp(tempSettings, mSuppressions, mErrorLoggerDirect, mTimerResults, mUseGlobalSuppressions, mExecuteCommand); // TODO: propagate back mFileInfo const unsigned int returnValue = temp.check(fs.file); if (mUnusedFunctionsCheck) @@ -837,7 +837,7 @@ unsigned int CppCheck::check(const FileSettings &fs) return returnValue; } // need to pass the externally provided ErrorLogger instead of our internal wrapper - CppCheck temp(tempSettings, mSuppressions, mErrorLoggerDirect, mUseGlobalSuppressions, mExecuteCommand); + CppCheck temp(tempSettings, mSuppressions, mErrorLoggerDirect, mTimerResults, mUseGlobalSuppressions, mExecuteCommand); const unsigned int returnValue = temp.checkFile(fs.file, fs.cfg, fs.fileIndex); if (mUnusedFunctionsCheck) mUnusedFunctionsCheck->updateFunctionData(*temp.mUnusedFunctionsCheck); @@ -1039,7 +1039,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str // Get configurations.. std::set configurations; if (maxConfigs > 1) { - Timer::run("Preprocessor::getConfigs", mSettings.showtime, &s_timerResults, [&]() { + Timer::run("Preprocessor::getConfigs", mSettings.showtime, mTimerResults, [&]() { configurations = preprocessor.getConfigs(); }); } else { @@ -1124,7 +1124,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str if (mSettings.preprocessOnly) { std::string codeWithoutCfg; - Timer::run("Preprocessor::getcode", mSettings.showtime, &s_timerResults, [&]() { + Timer::run("Preprocessor::getcode", mSettings.showtime, mTimerResults, [&]() { codeWithoutCfg = preprocessor.getcode(currentConfig, files, true); }); @@ -1148,7 +1148,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str { bool skipCfg = false; // Create tokens, skip rest of iteration if failed - Timer::run("Tokenizer::createTokens", mSettings.showtime, &s_timerResults, [&]() { + Timer::run("Tokenizer::createTokens", mSettings.showtime, mTimerResults, [&]() { simplecpp::OutputList outputList_cfg; simplecpp::TokenList tokensP = preprocessor.preprocess(currentConfig, files, outputList_cfg); const simplecpp::Output* o = preprocessor.handleErrors(outputList_cfg); @@ -1175,7 +1175,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str Tokenizer tokenizer(std::move(tokenlist), mErrorLogger); try { if (mSettings.showtime != ShowTime::NONE) - tokenizer.setTimerResults(&s_timerResults); + tokenizer.setTimerResults(mTimerResults); tokenizer.setDirectives(directives); // TODO: how to avoid repeated copies? // locations macros @@ -1288,8 +1288,8 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str // TODO: clear earlier? mLogger->clear(); - if (mSettings.showtime == ShowTime::FILE || mSettings.showtime == ShowTime::TOP5_FILE) - printTimerResults(mSettings.showtime); + if (mTimerResults && (mSettings.showtime == ShowTime::FILE || mSettings.showtime == ShowTime::TOP5_FILE)) + mTimerResults->showResults(mSettings.showtime); return mLogger->exitcode(); } @@ -1346,7 +1346,7 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer, AnalyzerInformation return; } - Timer::run(check->name() + "::runChecks", mSettings.showtime, &s_timerResults, [&]() { + Timer::run(check->name() + "::runChecks", mSettings.showtime, mTimerResults, [&]() { check->runChecks(tokenizer, &mErrorLogger); }); } @@ -1481,7 +1481,7 @@ void CppCheck::executeAddons(const std::string& dumpFile, const FileWithDetails& { if (!dumpFile.empty()) { std::vector f{dumpFile}; - Timer::run("CppCheck::executeAddons", mSettings.showtime, &s_timerResults, [&]() { + Timer::run("CppCheck::executeAddons", mSettings.showtime, mTimerResults, [&]() { executeAddons(f, file.spath()); }); } @@ -1692,7 +1692,7 @@ void CppCheck::getErrorMessages(ErrorLogger &errorlogger) settings.templateFormat = "{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"; // TODO: get rid of this Suppressions supprs; - CppCheck cppcheck(settings, supprs, errorlogger, true, nullptr); + CppCheck cppcheck(settings, supprs, errorlogger, nullptr, true, nullptr); cppcheck.purgedConfigurationMessage("",""); cppcheck.tooManyConfigsError("",0U); // TODO: add functions to get remaining error messages @@ -1874,17 +1874,6 @@ unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const st return mLogger->exitcode(); } -// cppcheck-suppress unusedFunction - only used in tests -void CppCheck::resetTimerResults() -{ - s_timerResults.reset(); -} - -void CppCheck::printTimerResults(ShowTime mode) -{ - s_timerResults.showResults(mode); -} - bool CppCheck::isPremiumCodingStandardId(const std::string& id) const { if (mSettings.premiumArgs.find("--misra") != std::string::npos && startsWith(id, "premium-misra-")) return true; diff --git a/lib/cppcheck.h b/lib/cppcheck.h index 44286c294d2..22423689cdf 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -25,7 +25,6 @@ #include "config.h" #include -#include #include #include #include @@ -33,7 +32,6 @@ #include class TokenList; -enum class ShowTime : std::uint8_t; struct FileSettings; class CheckUnusedFunctions; class Tokenizer; @@ -43,6 +41,7 @@ class ErrorLogger; class Settings; struct Suppressions; class Preprocessor; +class TimerResults; namespace simplecpp { class TokenList; @@ -71,6 +70,7 @@ class CPPCHECKLIB CppCheck { CppCheck(const Settings& settings, Suppressions& supprs, ErrorLogger &errorLogger, + TimerResults* timerResults, bool useGlobalSuppressions, ExecuteCmdFn executeCommand); @@ -142,9 +142,6 @@ class CPPCHECKLIB CppCheck { /** analyse whole program use .analyzeinfo files or ctuinfo string */ unsigned int analyseWholeProgram(const std::string &buildDir, const std::list &files, const std::list& fileSettings, const std::string& ctuInfo); - static void resetTimerResults(); - static void printTimerResults(ShowTime mode); - private: void purgedConfigurationMessage(const std::string &file, const std::string& configuration); @@ -246,6 +243,7 @@ class CPPCHECKLIB CppCheck { ErrorLogger& mErrorLogger; /** the ErrorLogger provided to this instance */ ErrorLogger& mErrorLoggerDirect; + TimerResults* mTimerResults; bool mUseGlobalSuppressions; diff --git a/lib/timer.h b/lib/timer.h index f50b3ca3485..c3d477d5802 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -56,7 +56,7 @@ struct TimerResultsData { static std::string durationToString(std::chrono::milliseconds duration); }; -class CPPCHECKLIB TimerResults : public TimerResultsIntf { +class CPPCHECKLIB WARN_UNUSED TimerResults : public TimerResultsIntf { public: TimerResults() = default; diff --git a/oss-fuzz/main.cpp b/oss-fuzz/main.cpp index 65c350c920a..8500bb966cb 100644 --- a/oss-fuzz/main.cpp +++ b/oss-fuzz/main.cpp @@ -63,7 +63,7 @@ static const FileWithDetails s_file("test.cpp", Standards::Language::CPP, 0); static void doCheck(const uint8_t *data, size_t dataSize) { Suppressions supprs; - CppCheck cppcheck(s_settings, supprs, s_errorLogger, false, nullptr); + CppCheck cppcheck(s_settings, supprs, s_errorLogger, nullptr, false, nullptr); cppcheck.checkBuffer(s_file, reinterpret_cast(data), dataSize); } diff --git a/test/fixture.cpp b/test/fixture.cpp index 5585ab58b58..b59b47855f7 100644 --- a/test/fixture.cpp +++ b/test/fixture.cpp @@ -18,7 +18,6 @@ #include "fixture.h" -#include "cppcheck.h" #include "errortypes.h" #include "helpers.h" #include "library.h" @@ -94,7 +93,6 @@ bool TestFixture::prepareTest(const char testname[]) { mTemplateFormat.clear(); mTemplateLocation.clear(); - CppCheck::resetTimerResults(); prepareTestInternal(); diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index 35b25175023..2de32efb022 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -196,7 +196,7 @@ class TestCppcheck : public TestFixture { if (tools && !nocmd) { f = getExecuteCommand(fname, called); } - CppCheck cppcheck(s, supprs, errorLogger, false, f); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, f); ASSERT_EQUALS(1, cppcheck.check(FileWithDetails(file.path(), Path::identify(file.path(), false), 0))); // TODO: how to properly disable these warnings? errorLogger.ids.erase(std::remove_if(errorLogger.ids.begin(), errorLogger.ids.end(), [](const std::string& id) { @@ -280,7 +280,7 @@ class TestCppcheck : public TestFixture { if (tools && !nocmd) { f = getExecuteCommand(fname, called); } - CppCheck cppcheck(s, supprs, errorLogger, false, f); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, f); FileSettings fs{file.path(), Path::identify(file.path(), false), 0}; ASSERT_EQUALS(1, cppcheck.check(fs)); // TODO: how to properly disable these warnings? @@ -348,7 +348,7 @@ class TestCppcheck : public TestFixture { const Settings s = settingsBuilder().libraryxml(xmldata).build(); Suppressions supprs; ErrorLogger2 errorLogger; - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); ASSERT_EQUALS(0, cppcheck.check(FileWithDetails(file.path(), Path::identify(file.path(), false), 0))); // TODO: how to properly disable these warnings? errorLogger.ids.erase(std::remove_if(errorLogger.ids.begin(), errorLogger.ids.end(), [](const std::string& id) { @@ -374,7 +374,7 @@ class TestCppcheck : public TestFixture { const auto s = dinit(Settings, $.templateFormat = templateFormat); // TODO: remove when we only longer rely on toString() in unique message handling Suppressions supprs; ErrorLogger2 errorLogger; - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); ASSERT_EQUALS(1, cppcheck.check(FileWithDetails(test_file_a.path(), Path::identify(test_file_a.path(), false), 0))); ASSERT_EQUALS(1, cppcheck.check(FileWithDetails(test_file_b.path(), Path::identify(test_file_b.path(), false), 0))); // TODO: how to properly disable these warnings? @@ -406,7 +406,7 @@ class TestCppcheck : public TestFixture { const auto s = dinit(Settings, $.templateFormat = templateFormat); // TODO: remove when we only longer rely on toString() in unique message handling? Suppressions supprs; ErrorLogger2 errorLogger; - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); ASSERT_EQUALS(1, cppcheck.check(FileWithDetails(test_file.path(), Path::identify(test_file.path(), false), 0))); // TODO: how to properly disable these warnings? errorLogger.errmsgs.erase(std::remove_if(errorLogger.errmsgs.begin(), errorLogger.errmsgs.end(), [](const ErrorMessage& msg) { @@ -440,7 +440,7 @@ class TestCppcheck : public TestFixture { { const auto s = dinit(Settings, $.premiumArgs = ""); - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); ASSERT_EQUALS(false, cppcheck.isPremiumCodingStandardId("misra-c2012-0.0")); ASSERT_EQUALS(false, cppcheck.isPremiumCodingStandardId("misra-c2023-0.0")); @@ -457,7 +457,7 @@ class TestCppcheck : public TestFixture { { const auto s = dinit(Settings, $.premiumArgs = "--misra-c-2012 --cert-c++-2016 --autosar"); - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); ASSERT_EQUALS(false, cppcheck.isPremiumCodingStandardId("misra-c2012-0.0")); ASSERT_EQUALS(true, cppcheck.isPremiumCodingStandardId("premium-misra-c-2012-0.0")); @@ -477,7 +477,7 @@ class TestCppcheck : public TestFixture { s.basePaths.emplace_back("/some/path"); Suppressions supprs; ErrorLogger2 errorLogger; - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); std::vector files{"/some/path/test.c"}; simplecpp::TokenList tokens1(files); const std::string expected = " \n" @@ -508,7 +508,7 @@ class TestCppcheck : public TestFixture { { Settings s; s.libraries.emplace_back("std.cfg"); - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); //std::vector files{ "/some/path/test.c" }; const std::string expected = " \n"; ASSERT_EQUALS(expected, cppcheck.getLibraryDumpData()); @@ -518,7 +518,7 @@ class TestCppcheck : public TestFixture { Settings s; s.libraries.emplace_back("std.cfg"); s.libraries.emplace_back("posix.cfg"); - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); const std::string expected = " \n \n"; ASSERT_EQUALS(expected, cppcheck.getLibraryDumpData()); } @@ -532,7 +532,7 @@ class TestCppcheck : public TestFixture { { const auto s = dinit(Settings, $.templateFormat = templateFormat, $.plistOutput = "output"); const ScopedFile file("file", ""); - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); const FileWithDetails fileWithDetails {file.path(), Path::identify(file.path(), false), 0}; cppcheck.checkPlistOutput(fileWithDetails, files); @@ -544,7 +544,7 @@ class TestCppcheck : public TestFixture { { const auto s = dinit(Settings, $.plistOutput = "output"); const ScopedFile file("file.c", ""); - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); const FileWithDetails fileWithDetails {file.path(), Path::identify(file.path(), false), 0}; cppcheck.checkPlistOutput(fileWithDetails, files); @@ -556,7 +556,7 @@ class TestCppcheck : public TestFixture { { Settings s; const ScopedFile file("file.c", ""); - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); cppcheck.checkPlistOutput(FileWithDetails(file.path(), Path::identify(file.path(), false), 0), files); } } @@ -585,7 +585,7 @@ class TestCppcheck : public TestFixture { settings.addonInfos.push_back(premiumaddon); settings.premiumArgs = "misra-c-2012"; - CppCheck check(settings, supprs, errorLogger, false, {}); + CppCheck check(settings, supprs, errorLogger, nullptr, false, {}); const size_t hash1 = check.calculateHash(preprocessor); settings.premiumArgs = ""; @@ -609,7 +609,7 @@ class TestCppcheck : public TestFixture { $.debugwarnings = true); Suppressions supprs; ErrorLogger2 errorLogger; - CppCheck cppcheck(s, supprs, errorLogger, false, {}); + CppCheck cppcheck(s, supprs, errorLogger, nullptr, false, {}); ASSERT_EQUALS(1, cppcheck.check(FileWithDetails(test_file.path(), Path::identify(test_file.path(), false), 0))); // TODO: how to properly disable these warnings? errorLogger.errmsgs.erase(std::remove_if(errorLogger.errmsgs.begin(), errorLogger.errmsgs.end(), [](const ErrorMessage& msg) { diff --git a/test/testexecutor.cpp b/test/testexecutor.cpp index 9e495640523..a0e5e02f1fb 100644 --- a/test/testexecutor.cpp +++ b/test/testexecutor.cpp @@ -36,7 +36,7 @@ class DummyExecutor : public Executor { public: DummyExecutor(const std::list &files, const std::list& fileSettings, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger) - : Executor(files, fileSettings, settings, suppressions, errorLogger) + : Executor(files, fileSettings, settings, suppressions, errorLogger, nullptr) {} NORETURN unsigned int check() override diff --git a/test/testprocessexecutor.cpp b/test/testprocessexecutor.cpp index 1866234ac78..c430116110e 100644 --- a/test/testprocessexecutor.cpp +++ b/test/testprocessexecutor.cpp @@ -104,6 +104,7 @@ class TestProcessExecutorBase : public TestFixture { s.plistOutput = opt.plistOutput; s.templateFormat = "{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"; Suppressions supprs; + TimerResults timerResults; // NOLINTNEXTLINE(performance-unnecessary-value-param) auto executeFn = [](std::string,std::vector,std::string,std::string&){ @@ -119,7 +120,7 @@ class TestProcessExecutorBase : public TestFixture { if (useFS) filelist.clear(); - ProcessExecutor executor(filelist, fileSettings, s, supprs, *this, executeFn); + ProcessExecutor executor(filelist, fileSettings, s, supprs, *this, &timerResults, executeFn); ASSERT_EQUALS(result, executor.check()); } #endif // HAS_THREADING_MODEL_FORK diff --git a/test/testsingleexecutor.cpp b/test/testsingleexecutor.cpp index feb760e5381..4e1a258d19b 100644 --- a/test/testsingleexecutor.cpp +++ b/test/testsingleexecutor.cpp @@ -97,9 +97,10 @@ class TestSingleExecutorBase : public TestFixture { s.templateFormat = "{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"; // TODO: remove when we only longer rely on toString() in unique message handling? Suppressions supprs; + TimerResults timerResults; // NOLINTNEXTLINE(performance-unnecessary-value-param) - CppCheck cppcheck(s, supprs, *this, true, [](std::string,std::vector,std::string,std::string&){ + CppCheck cppcheck(s, supprs, *this, &timerResults, true, [](std::string,std::vector,std::string,std::string&){ return EXIT_SUCCESS; }); @@ -112,7 +113,7 @@ class TestSingleExecutorBase : public TestFixture { if (useFS) filelist.clear(); - SingleExecutor executor(cppcheck, filelist, fileSettings, s, supprs, *this); + SingleExecutor executor(cppcheck, filelist, fileSettings, s, supprs, *this, &timerResults); ASSERT_EQUALS(result, executor.check()); } diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index 1f572bd2eb2..58ee72f28b3 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -31,7 +31,6 @@ #include "suppressions.h" #include "threadexecutor.h" -#include #include #include #include @@ -286,8 +285,8 @@ class TestSuppressions : public TestFixture { if (useFS) filelist.clear(); - CppCheck cppCheck(settings, supprs, *this, true, nullptr); - SingleExecutor executor(cppCheck, filelist, fileSettings, settings, supprs, *this); + CppCheck cppCheck(settings, supprs, *this, nullptr, true, nullptr); + SingleExecutor executor(cppCheck, filelist, fileSettings, settings, supprs, *this, nullptr); unsigned int exitCode = executor.check(); const bool err = CppCheckExecutor::reportUnmatchedSuppressions(settings, supprs.nomsg, filelist, fileSettings, *this); @@ -336,7 +335,7 @@ class TestSuppressions : public TestFixture { if (useFS) filelist.clear(); - ThreadExecutor executor(filelist, fileSettings, settings, supprs, *this, CppCheckExecutor::executeCommand); + ThreadExecutor executor(filelist, fileSettings, settings, supprs, *this, nullptr, CppCheckExecutor::executeCommand); unsigned int exitCode = executor.check(); const bool err = CppCheckExecutor::reportUnmatchedSuppressions(settings, supprs.nomsg, filelist, fileSettings, *this); @@ -386,7 +385,7 @@ class TestSuppressions : public TestFixture { if (useFS) filelist.clear(); - ProcessExecutor executor(filelist, fileSettings, settings, supprs, *this, CppCheckExecutor::executeCommand); + ProcessExecutor executor(filelist, fileSettings, settings, supprs, *this, nullptr, CppCheckExecutor::executeCommand); unsigned int exitCode = executor.check(); const bool err = CppCheckExecutor::reportUnmatchedSuppressions(settings, supprs.nomsg, filelist, fileSettings, *this); @@ -1310,7 +1309,7 @@ class TestSuppressions : public TestFixture { Suppressions supprs; ASSERT_EQUALS("", supprs.nomsg.addSuppressionLine("uninitvar")); - CppCheck cppCheck(settings, supprs, *this, false, nullptr); // <- do not "use global suppressions". pretend this is a thread that just checks a file. + CppCheck cppCheck(settings, supprs, *this, nullptr, false, nullptr); // <- do not "use global suppressions". pretend this is a thread that just checks a file. const char code[] = "int f() { int a; return a; }"; ASSERT_EQUALS(0, cppCheck.checkBuffer(FileWithDetails("test.c", Standards::Language::C, 0),code, sizeof(code))); // <- no unsuppressed error is seen @@ -1352,7 +1351,7 @@ class TestSuppressions : public TestFixture { " // cppcheck-suppress unusedStructMember\n" " int y;\n" "};"; - CppCheck cppCheck(settings, supprs, *this, true, nullptr); + CppCheck cppCheck(settings, supprs, *this, nullptr, true, nullptr); ASSERT_EQUALS(0, cppCheck.checkBuffer(FileWithDetails("/somewhere/test.cpp", Standards::Language::CPP, 0), code, sizeof(code))); ASSERT_EQUALS("",errout_str()); } diff --git a/test/testthreadexecutor.cpp b/test/testthreadexecutor.cpp index 106a5bc9078..27d88e1d699 100644 --- a/test/testthreadexecutor.cpp +++ b/test/testthreadexecutor.cpp @@ -105,6 +105,7 @@ class TestThreadExecutorBase : public TestFixture { s.templateFormat = "{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"; // TODO: remove when we only longer rely on toString() in unique message handling? Suppressions supprs; + TimerResults timerResults; // NOLINTNEXTLINE(performance-unnecessary-value-param) auto executeFn = [](std::string,std::vector,std::string,std::string&){ @@ -120,7 +121,7 @@ class TestThreadExecutorBase : public TestFixture { if (useFS) filelist.clear(); - ThreadExecutor executor(filelist, fileSettings, s, supprs, *this, executeFn); + ThreadExecutor executor(filelist, fileSettings, s, supprs, *this, &timerResults, executeFn); ASSERT_EQUALS(result, executor.check()); } #endif // HAS_THREADING_MODEL_THREAD