From d3a2cdc26c62882bc9e3dd7065ae442a3b57ab40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 30 Dec 2022 21:21:05 +0100 Subject: [PATCH] converted (undocumented) define `MAXTIME` into (undocumented) command-line options `--checks-max-time=`, `--template-max-time=` and `--typedef-max-time=` (#4661) --- cli/cmdlineparser.cpp | 12 ++++++++++++ lib/config.h | 4 ++++ lib/cppcheck.cpp | 16 ++++++++++++++- lib/settings.cpp | 3 +++ lib/settings.h | 9 +++++++++ lib/templatesimplifier.cpp | 40 ++++++++++++++++++++++++++++---------- lib/tokenize.cpp | 37 ++++++++++++++++++++--------------- lib/tokenize.h | 14 ------------- 8 files changed, 94 insertions(+), 41 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index d6eda8494..6de62e5c0 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -250,6 +250,10 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) mSettings->addEnabled("information"); } + else if (std::strncmp(argv[i], "--checks-max-time=", 18) == 0) { + mSettings->checksMaxTime = std::atoi(argv[i] + 18); + } + else if (std::strcmp(argv[i], "--clang") == 0) { mSettings->clang = true; } @@ -915,6 +919,14 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) } } + else if (std::strncmp(argv[i], "--template-max-time=", 20) == 0) { + mSettings->templateMaxTime = std::atoi(argv[i] + 20); + } + + else if (std::strncmp(argv[i], "--typedef-max-time=", 19) == 0) { + mSettings->typedefMaxTime = std::atoi(argv[i] + 19); + } + else if (std::strncmp(argv[i], "--valueflow-max-iterations=", 27) == 0) { long tmp; try { diff --git a/lib/config.h b/lib/config.h index 05d8b8238..225bf7ed3 100644 --- a/lib/config.h +++ b/lib/config.h @@ -19,6 +19,10 @@ #ifndef configH #define configH +#ifdef MAXTIME +#error "MAXTIME is no longer supported - please use command-line options --checks-max-time=, --template-max-time= and --typedef-max-time= instead" +#endif + #ifdef _WIN32 # ifdef CPPCHECKLIB_EXPORT # define CPPCHECKLIB __declspec(dllexport) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 27c0d4070..58c4fa719 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1055,13 +1055,27 @@ 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; + // call all "runChecks" in all registered Check classes for (Check *check : Check::instances()) { if (Settings::terminated()) return; - if (Tokenizer::isMaxTime()) + 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; + } if (doUnusedFunctionOnly && dynamic_cast(check) == nullptr) continue; diff --git a/lib/settings.cpp b/lib/settings.cpp index f2b6191ad..db856c667 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -39,6 +39,7 @@ Settings::Settings() checkConfiguration(false), checkHeaders(true), checkLibrary(false), + checksMaxTime(0), checkUnusedTemplates(true), clang(false), clangExecutable("clang"), @@ -66,6 +67,8 @@ Settings::Settings() relativePaths(false), reportProgress(false), showtime(SHOWTIME_MODES::SHOWTIME_NONE), + templateMaxTime(0), + typedefMaxTime(0), valueFlowMaxIterations(4), verbose(false), xml(false), diff --git a/lib/settings.h b/lib/settings.h index ed462d05a..afd92bb7c 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -125,6 +125,9 @@ public: /** Check for incomplete info in library files? */ bool checkLibrary; + /** @brief The maximum time in seconds for the checks of a single file */ + std::size_t checksMaxTime; + /** @brief check unknown function return values */ std::set checkUnknownFunctionReturn; @@ -342,6 +345,12 @@ public: * text mode, e.g. "{file}:{line} {info}" */ std::string templateLocation; + /** @brief The maximum time in seconds for the template instantation */ + std::size_t templateMaxTime; + + /** @brief The maximum time in seconds for the typedef simplification */ + std::size_t typedefMaxTime; + /** @brief defines given by the user */ std::string userDefines; diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 1e7aaeac5..b2960c210 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -3112,12 +3112,22 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( Token * const tok2 = instantiation.token(); if (mErrorLogger && !mTokenList.getFiles().empty()) mErrorLogger->reportProgress(mTokenList.getFiles()[0], "TemplateSimplifier::simplifyTemplateInstantiations()", tok2->progressValue()); -#ifdef MAXTIME - if (std::time(0) > maxtime) + + if (maxtime > 0 && std::time(nullptr) > maxtime) { + if (mSettings->debugwarnings) { + ErrorMessage::FileLocation loc; + loc.setfile(mTokenList.getFiles()[0]); + ErrorMessage errmsg({std::move(loc)}, + emptyString, + Severity::debug, + "Template instantation maximum time exceeded", + "templateMaxTime", + Certainty::normal); + mErrorLogger->reportErr(errmsg); + } return false; -#else - (void)maxtime; -#endif + } + assert(mTokenList.validateToken(tok2)); // that assertion fails on examples from #6021 const Token *startToken = tok2; @@ -3173,12 +3183,22 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( Token * tok2 = const_cast(templateDeclaration.nameToken()); if (mErrorLogger && !mTokenList.getFiles().empty()) mErrorLogger->reportProgress(mTokenList.getFiles()[0], "TemplateSimplifier::simplifyTemplateInstantiations()", tok2->progressValue()); -#ifdef MAXTIME - if (std::time(0) > maxtime) + + if (maxtime > 0 && std::time(nullptr) > maxtime) { + if (mSettings->debugwarnings) { + ErrorMessage::FileLocation loc; + loc.setfile(mTokenList.getFiles()[0]); + ErrorMessage errmsg({std::move(loc)}, + emptyString, + Severity::debug, + "Template instantation maximum time exceeded", + "templateMaxTime", + Certainty::normal); + mErrorLogger->reportErr(errmsg); + } return false; -#else - (void)maxtime; -#endif + } + assert(mTokenList.validateToken(tok2)); // that assertion fails on examples from #6021 Token *startToken = tok2; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index ae0b92ede..87c42d9f0 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -164,11 +164,8 @@ Tokenizer::Tokenizer() : mVarId(0), mUnnamedCount(0), mCodeWithTemplates(false), //is there any templates? - mTimerResults(nullptr) -#ifdef MAXTIME - , mMaxTime(std::time(0) + MAXTIME) -#endif - , mPreprocessor(nullptr) + mTimerResults(nullptr), + mPreprocessor(nullptr) {} Tokenizer::Tokenizer(const Settings *settings, ErrorLogger *errorLogger) : @@ -180,11 +177,8 @@ Tokenizer::Tokenizer(const Settings *settings, ErrorLogger *errorLogger) : mVarId(0), mUnnamedCount(0), mCodeWithTemplates(false), //is there any templates? - mTimerResults(nullptr) -#ifdef MAXTIME - ,mMaxTime(std::time(0) + MAXTIME) -#endif - , mPreprocessor(nullptr) + mTimerResults(nullptr), + mPreprocessor(nullptr) { // make sure settings are specified assert(mSettings); @@ -614,6 +608,8 @@ void Tokenizer::simplifyTypedef() // Convert "using a::b;" to corresponding typedef statements simplifyUsingToTypedef(); + const std::time_t maxTime = mSettings->typedefMaxTime > 0 ? std::time(nullptr) + mSettings->typedefMaxTime: 0; + for (Token *tok = list.front(); tok; tok = tok->next()) { if (mErrorLogger && !list.getFiles().empty()) mErrorLogger->reportProgress(list.getFiles()[0], "Tokenize (typedef)", tok->progressValue()); @@ -621,8 +617,20 @@ void Tokenizer::simplifyTypedef() if (Settings::terminated()) return; - if (isMaxTime()) + if (maxTime > 0 && std::time(nullptr) > maxTime) { + if (mSettings->debugwarnings) { + ErrorMessage::FileLocation loc; + loc.setfile(list.getFiles()[0]); + ErrorMessage errmsg({std::move(loc)}, + emptyString, + Severity::debug, + "Typedef simplification instantation maximum time exceeded", + "typedefMaxTime", + Certainty::normal); + mErrorLogger->reportErr(errmsg); + } return; + } if (goback) { //jump back once, see the comment at the end of the function @@ -3461,12 +3469,9 @@ void Tokenizer::simplifyTemplates() if (isC()) return; + const std::time_t maxTime = mSettings->templateMaxTime > 0 ? std::time(nullptr) + mSettings->templateMaxTime : 0; mTemplateSimplifier->simplifyTemplates( -#ifdef MAXTIME - mMaxTime, -#else - 0, // ignored -#endif + maxTime, mCodeWithTemplates); } //--------------------------------------------------------------------------- diff --git a/lib/tokenize.h b/lib/tokenize.h index 28934713f..52a0a2ebb 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -680,15 +680,6 @@ public: */ static const Token * startOfExecutableScope(const Token * tok); -#ifdef MAXTIME - bool isMaxTime() const { - return (std::time(0) > mMaxTime); -#else - static bool isMaxTime() { - return false; -#endif - } - const Settings *getSettings() const { return mSettings; } @@ -759,11 +750,6 @@ private: */ TimerResults *mTimerResults; -#ifdef MAXTIME - /** Tokenizer maxtime */ - const std::time_t mMaxTime; -#endif - const Preprocessor *mPreprocessor; };