From 7726a5b5b3b4be84e18639ac5c3b64afb7404caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 9 Apr 2023 13:48:13 +0200 Subject: [PATCH] Add a --check-level option (#4942) --- .github/workflows/CI-unixish.yml | 4 ++-- .selfcheck_suppressions | 2 -- cli/cmdlineparser.cpp | 21 +++++++++++++++------ lib/settings.cpp | 14 ++++++++++++++ lib/settings.h | 5 ++++- lib/valueflow.cpp | 7 ++----- 6 files changed, 37 insertions(+), 16 deletions(-) diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml index ba1997ae8..ed7319052 100644 --- a/.github/workflows/CI-unixish.yml +++ b/.github/workflows/CI-unixish.yml @@ -446,7 +446,7 @@ jobs: - name: Self check run: | - selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings" + selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings --check-level=exhaustive" ec=0 # early exit @@ -464,4 +464,4 @@ jobs: ./cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 # triage ./cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt -Itools/triage/temp -Igui tools/triage/*.cpp tools/triage/temp/*.cpp || ec=1 - exit $ec \ No newline at end of file + exit $ec diff --git a/.selfcheck_suppressions b/.selfcheck_suppressions index b6fd4de66..1f9a8d9aa 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -24,5 +24,3 @@ autoNoType bailoutUninitVar *:externals/*/* - -performanceValueflowMaxIfCountExceeded diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index b6233aa48..2ee6c0082 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -254,6 +254,14 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) else if (std::strcmp(argv[i], "--check-config") == 0) mSettings.checkConfiguration = true; + // Check code exhaustively + else if (std::strcmp(argv[i], "--check-level=exhaustive") == 0) + mSettings.setCheckLevelExhaustive(); + + // Check code with normal analysis + else if (std::strcmp(argv[i], "--check-level=normal") == 0) + mSettings.setCheckLevelNormal(); + // Check library definitions else if (std::strcmp(argv[i], "--check-library") == 0) { mSettings.checkLibrary = true; @@ -1092,6 +1100,13 @@ void CmdLineParser::printHelp() " execute clang/clang-tidy/addons.\n" " --check-config Check cppcheck configuration. The normal code\n" " analysis is disabled by this flag.\n" + " --check-level=\n" + " Configure how much checking you want:\n" + " * normal: Cppcheck uses some compromises in the checking so\n" + " the checking will finish in reasonable time.\n" + " * exhaustive: deeper analysis that you choose when you can\n" + " wait.\n" + " The default choice is 'normal'.\n" " --check-library Show information messages when library files have\n" " incomplete info.\n" " --clang= Experimental: Use Clang parser instead of the builtin Cppcheck\n" @@ -1214,12 +1229,6 @@ void CmdLineParser::printHelp() " is 2. A larger value will mean more errors can be found\n" " but also means the analysis will be slower.\n" " --output-file= Write results to file, rather than standard error.\n" - " --performance-valueflow-max-if-count=\n" - " If you have many conditional scopes in a function then\n" - " the number of possible control flow paths through that\n" - " function explodes and that can lead to very long analysis\n" - " time. Valueflow is limited in functions that have more\n" - " than conditional scopes.\n" " --platform=, --platform=\n" " Specifies platform specific types and sizes. The\n" " available builtin platforms are:\n" diff --git a/lib/settings.cpp b/lib/settings.cpp index e7c669703..9b79b5f3f 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -78,6 +78,7 @@ Settings::Settings() { severity.setEnabled(Severity::error, true); certainty.setEnabled(Certainty::normal, true); + setCheckLevelNormal(); } void Settings::loadCppcheckCfg() @@ -222,3 +223,16 @@ void Settings::loadSummaries() { Summaries::loadReturn(buildDir, summaryReturn); } + + +void Settings::setCheckLevelExhaustive() +{ + // Checking can take a little while. ~ 10 times slower than normal analysis is OK. + performanceValueFlowMaxIfCount = -1; +} + +void Settings::setCheckLevelNormal() +{ + // Checking should finish in reasonable time. + performanceValueFlowMaxIfCount = 100; +} diff --git a/lib/settings.h b/lib/settings.h index e8fe93975..ed65fd2bb 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -250,7 +250,7 @@ public: int performanceValueFlowMaxTime; /** @brief --performance-valueflow-max-if-count=C */ - int performanceValueFlowMaxIfCount = 100; + int performanceValueFlowMaxIfCount; /** @brief plist output (--plist-output=<dir>) */ std::string plistOutput; @@ -438,6 +438,9 @@ public: return jobs == 1; } + void setCheckLevelExhaustive(); + void setCheckLevelNormal(); + private: static std::string parseEnabled(const std::string &str, std::tuple, SimpleEnableGroup> &groups); std::string applyEnabled(const std::string &str, bool enable); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 9e35b76c4..9ffea1a16 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -9106,11 +9106,8 @@ void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase, const std::string& functionName = functionScope->className; const std::list callstack(1, ErrorMessage::FileLocation(functionScope->bodyStart, tokenlist)); const ErrorMessage errmsg(callstack, tokenlist->getSourceFilePath(), Severity::information, - "ValueFlow analysis is limited in " + functionName + " because if-count in function " + - std::to_string(countIfScopes) + " exceeds limit " + - std::to_string(settings->performanceValueFlowMaxIfCount) + ". The limit can be adjusted with " - "--performance-valueflow-max-if-count. Increasing the if-count limit will likely increase the " - "analysis time.", "performanceValueflowMaxIfCountExceeded", Certainty::normal); + "ValueFlow analysis is limited in " + functionName + ". Use --check-level=exhaustive if full analysis is wanted.", + "checkLevelNormal", Certainty::normal); errorLogger->reportErr(errmsg); } }