From 6c5f0b8eae981d4f9fa2229c71ca60e48334dfb9 Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 1 Jul 2024 01:41:26 +0200 Subject: [PATCH] got rid of global `CTU::maxCtuDepth` --- cli/cmdlineparser.cpp | 8 +++++++- lib/checkbufferoverrun.cpp | 10 +++++----- lib/checkbufferoverrun.h | 2 +- lib/checknullpointer.cpp | 3 ++- lib/checkuninitvar.cpp | 3 ++- lib/cppcheck.cpp | 5 ----- lib/ctu.cpp | 16 ++++++++-------- lib/ctu.h | 5 ++--- releasenotes.txt | 1 + test/testcmdlineparser.cpp | 19 ++++++++++++++++++- 10 files changed, 46 insertions(+), 26 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 5ec8faafad1..c5e3946775d 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -903,8 +903,14 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a // max ctu depth else if (std::strncmp(argv[i], "--max-ctu-depth=", 16) == 0) { - if (!parseNumberArg(argv[i], 16, mSettings.maxCtuDepth)) + int temp = 0; + if (!parseNumberArg(argv[i], 16, temp)) return Result::Fail; + if (temp > 10) { + mLogger.printMessage("--max-ctu-depth is being capped at 10. This limitation will be removed in a future Cppcheck version."); + temp = 10; + } + mSettings.maxCtuDepth = temp; } else if (std::strcmp(argv[i], "--no-cpp-header-probe") == 0) { diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index cc769deebe0..0a61f56345c 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -987,7 +987,6 @@ bool CheckBufferOverrun::analyseWholeProgram(const CTU::FileInfo *ctu, const std if (!ctu) return false; bool foundErrors = false; - (void)settings; // This argument is unused CheckBufferOverrun dummy(nullptr, &settings, &errorLogger); dummy. @@ -1000,14 +999,14 @@ bool CheckBufferOverrun::analyseWholeProgram(const CTU::FileInfo *ctu, const std if (!fi) continue; for (const CTU::FileInfo::UnsafeUsage &unsafeUsage : fi->unsafeArrayIndex) - foundErrors |= analyseWholeProgram1(callsMap, unsafeUsage, 1, errorLogger); + foundErrors |= analyseWholeProgram1(callsMap, unsafeUsage, 1, errorLogger, settings.maxCtuDepth); for (const CTU::FileInfo::UnsafeUsage &unsafeUsage : fi->unsafePointerArith) - foundErrors |= analyseWholeProgram1(callsMap, unsafeUsage, 2, errorLogger); + foundErrors |= analyseWholeProgram1(callsMap, unsafeUsage, 2, errorLogger, settings.maxCtuDepth); } return foundErrors; } -bool CheckBufferOverrun::analyseWholeProgram1(const std::map> &callsMap, const CTU::FileInfo::UnsafeUsage &unsafeUsage, int type, ErrorLogger &errorLogger) +bool CheckBufferOverrun::analyseWholeProgram1(const std::map> &callsMap, const CTU::FileInfo::UnsafeUsage &unsafeUsage, int type, ErrorLogger &errorLogger, int maxCtuDepth) { const CTU::FileInfo::FunctionCall *functionCall = nullptr; @@ -1017,7 +1016,8 @@ bool CheckBufferOverrun::analyseWholeProgram1(const std::map> &callsMap, const CTU::FileInfo::UnsafeUsage &unsafeUsage, int type, ErrorLogger &errorLogger); + static bool analyseWholeProgram1(const std::map> &callsMap, const CTU::FileInfo::UnsafeUsage &unsafeUsage, int type, ErrorLogger &errorLogger, int maxCtuDepth); static std::string myName() { diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 87857c2d488..5717045e63c 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -637,7 +637,8 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo *ctu, const std:: callsMap, "Dereferencing argument ARG that is null", nullptr, - warning); + warning, + settings.maxCtuDepth); if (locationList.empty()) continue; diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 8d973d7e369..31473a18740 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1747,7 +1747,8 @@ bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo *ctu, const std::li callsMap, "Using argument ARG", &functionCall, - false); + false, + settings.maxCtuDepth); if (locationList.empty()) continue; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index c4923b0795b..4152e23d051 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1807,8 +1807,6 @@ void CppCheck::analyseClangTidy(const FileSettings &fileSettings) bool CppCheck::analyseWholeProgram() { bool errors = false; - // Init CTU - CTU::maxCtuDepth = mSettings.maxCtuDepth; // Analyse the tokens CTU::FileInfo ctu; if (mSettings.useSingleJob() || !mSettings.buildDir.empty()) @@ -1881,9 +1879,6 @@ unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const st } } - // Set CTU max depth - CTU::maxCtuDepth = mSettings.maxCtuDepth; - // Analyse the tokens // cppcheck-suppress shadowFunction - TODO: fix this for (Check *check : Check::instances()) diff --git a/lib/ctu.cpp b/lib/ctu.cpp index 0cf0273cfe0..d2387f4045e 100644 --- a/lib/ctu.cpp +++ b/lib/ctu.cpp @@ -55,8 +55,6 @@ static constexpr char ATTR_MY_ARGNR[] = "my-argnr"; static constexpr char ATTR_MY_ARGNAME[] = "my-argname"; static constexpr char ATTR_VALUE[] = "value"; -int CTU::maxCtuDepth = 2; - std::string CTU::getFunctionId(const Tokenizer &tokenizer, const Function *function) { return tokenizer.list.file(function->tokenDef) + ':' + std::to_string(function->tokenDef->linenr()) + ':' + std::to_string(function->tokenDef->column()); @@ -502,10 +500,11 @@ static bool findPath(const std::string &callId, const std::map> &callsMap, const CTU::FileInfo::CallBase *path[10], int index, - bool warning) + bool warning, + int maxCtuDepth) { - if (index >= CTU::maxCtuDepth || index >= 10) - return false; + if (index >= maxCtuDepth) + return false; // TODO: add bailout message? const std::map>::const_iterator it = callsMap.find(callId); if (it == callsMap.end()) @@ -543,7 +542,7 @@ static bool findPath(const std::string &callId, if (!nestedCall) continue; - if (findPath(nestedCall->myId, nestedCall->myArgNr, unsafeValue, invalidValue, callsMap, path, index + 1, warning)) { + if (findPath(nestedCall->myId, nestedCall->myArgNr, unsafeValue, invalidValue, callsMap, path, index + 1, warning, maxCtuDepth)) { path[index] = nestedCall; return true; } @@ -557,13 +556,14 @@ std::list CTU::FileInfo::getErrorPath(InvalidValueTy const std::map> &callsMap, const char info[], const FunctionCall ** const functionCallPtr, - bool warning) + bool warning, + int maxCtuDepth) { std::list locationList; const CTU::FileInfo::CallBase *path[10] = {nullptr}; - if (!findPath(unsafeUsage.myId, unsafeUsage.myArgNr, unsafeUsage.value, invalidValue, callsMap, path, 0, warning)) + if (!findPath(unsafeUsage.myId, unsafeUsage.myArgNr, unsafeUsage.value, invalidValue, callsMap, path, 0, warning, maxCtuDepth)) return locationList; const std::string value1 = (invalidValue == InvalidValueType::null) ? "null" : "uninitialized"; diff --git a/lib/ctu.h b/lib/ctu.h index 0a50bd63e47..dacc430bb0c 100644 --- a/lib/ctu.h +++ b/lib/ctu.h @@ -135,11 +135,10 @@ namespace CTU { const std::map> &callsMap, const char info[], const FunctionCall ** functionCallPtr, - bool warning); + bool warning, + int maxCtuDepth); }; - extern int maxCtuDepth; - CPPCHECKLIB std::string toString(const std::list &unsafeUsage); CPPCHECKLIB std::string getFunctionId(const Tokenizer &tokenizer, const Function *function); diff --git a/releasenotes.txt b/releasenotes.txt index ffee14f39fd..ac3f5eec5b4 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -16,6 +16,7 @@ Changed interface: Deprecations: - The previously deprecated support for Python 2.7 has been removed. please use Python 3 instead. +- The maximum value for --max-ctu-depth is currently capped at 10. This limitation will be removed in a future release. - Other: diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 0ffa3198f3a..96fa60e0954 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -323,6 +323,8 @@ class TestCmdlineParser : public TestFixture { TEST_CASE(loadAverageNotSupported); #endif TEST_CASE(maxCtuDepth); + TEST_CASE(maxCtuDepth2); + TEST_CASE(maxCtuDepthLimit); TEST_CASE(maxCtuDepthInvalid); TEST_CASE(performanceValueflowMaxTime); TEST_CASE(performanceValueflowMaxTimeInvalid); @@ -2110,10 +2112,25 @@ class TestCmdlineParser : public TestFixture { #endif void maxCtuDepth() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--max-ctu-depth=5", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv)); + ASSERT_EQUALS(5, settings->maxCtuDepth); + } + + void maxCtuDepth2() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--max-ctu-depth=10", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv)); + ASSERT_EQUALS(10, settings->maxCtuDepth); + } + + void maxCtuDepthLimit() { REDIRECT; const char * const argv[] = {"cppcheck", "--max-ctu-depth=12", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv)); - ASSERT_EQUALS(12, settings->maxCtuDepth); + ASSERT_EQUALS(10, settings->maxCtuDepth); + ASSERT_EQUALS("cppcheck: --max-ctu-depth is being capped at 10. This limitation will be removed in a future Cppcheck version.\n", logger->str()); } void maxCtuDepthInvalid() {