diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml index ba1997ae80b..ed73190527f 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 c61108cdc9c..ba35bede778 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -23,5 +23,3 @@ autoNoType bailoutUninitVar *:externals/*/* - -performanceValueflowMaxIfCountExceeded diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 5f2cf23c527..1f18e4d9e8f 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; @@ -1093,6 +1101,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" @@ -1215,12 +1230,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 e7c66970319..9b79b5f3f05 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 e8fe939759b..ed65fd2bb34 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -250,7 +250,7 @@ class CPPCHECKLIB Settings { 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 @@ class CPPCHECKLIB Settings { 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 9e35b76c40f..9ffea1a1699 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); } }