From 526a86dc60ed73f97b4753239594c536b83b7832 Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Sat, 13 Jul 2019 01:40:24 -0400 Subject: [PATCH] Fix recursiveCount in CheckLeakAutoVar to really be recursive count. (#1988) --- lib/checkleakautovar.cpp | 17 ++++++++--------- lib/checkleakautovar.h | 9 ++++----- test/testleakautovar.cpp | 8 ++++++++ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index d10f05a0a..5b93b8031 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -159,12 +159,10 @@ void CheckLeakAutoVar::check() if (scope->hasInlineOrLambdaFunction()) continue; - recursiveCount = 0; - // Empty variable info VarInfo varInfo; - checkScope(scope->bodyStart, &varInfo, notzero); + checkScope(scope->bodyStart, &varInfo, notzero, 0); varInfo.conditionalAlloc.clear(); @@ -236,12 +234,13 @@ static const Token * isFunctionCall(const Token * nameToken) void CheckLeakAutoVar::checkScope(const Token * const startToken, VarInfo *varInfo, - std::set notzero) + std::set notzero, + unsigned int recursiveCount) { // The C++ standard suggests a minimum of 256 nested control statements - // but MSVC has a limit of 100. Cppcheck is hitting 256 when checking itself. - if (++recursiveCount > 384) - throw InternalError(startToken, "Internal limit: CheckLeakAutoVar::checkScope() Maximum recursive count of 384 reached.", InternalError::LIMIT); + // but MSVC has a limit of 100. + if (++recursiveCount > 100) + throw InternalError(startToken, "Internal limit: CheckLeakAutoVar::checkScope() Maximum recursive count of 100 reached.", InternalError::LIMIT); std::map &alloctype = varInfo->alloctype; std::map &possibleUsage = varInfo->possibleUsage; @@ -471,10 +470,10 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, } } - checkScope(closingParenthesis->next(), &varInfo1, notzero); + checkScope(closingParenthesis->next(), &varInfo1, notzero, recursiveCount); closingParenthesis = closingParenthesis->linkAt(1); if (Token::simpleMatch(closingParenthesis, "} else {")) { - checkScope(closingParenthesis->tokAt(2), &varInfo2, notzero); + checkScope(closingParenthesis->tokAt(2), &varInfo2, notzero, recursiveCount); tok = closingParenthesis->linkAt(2)->previous(); } else { tok = closingParenthesis->previous(); diff --git a/lib/checkleakautovar.h b/lib/checkleakautovar.h index a27ce5553..de7107596 100644 --- a/lib/checkleakautovar.h +++ b/lib/checkleakautovar.h @@ -95,12 +95,12 @@ public: class CPPCHECKLIB CheckLeakAutoVar : public Check { public: /** This constructor is used when registering the CheckLeakAutoVar */ - CheckLeakAutoVar() : Check(myName()), recursiveCount(0) { + CheckLeakAutoVar() : Check(myName()) { } /** This constructor is used when running checks. */ CheckLeakAutoVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) - : Check(myName(), tokenizer, settings, errorLogger), recursiveCount(0) { + : Check(myName(), tokenizer, settings, errorLogger) { } void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) OVERRIDE { @@ -116,7 +116,8 @@ private: /** check for leaks in a function scope */ void checkScope(const Token * const startToken, VarInfo *varInfo, - std::set notzero); + std::set notzero, + unsigned int recursiveCount); /** Check token inside expression. * @param tok token inside expression. @@ -163,8 +164,6 @@ private: std::string classInfo() const OVERRIDE { return "Detect when a auto variable is allocated but not deallocated or deallocated twice.\n"; } - - unsigned int recursiveCount; }; /// @} //--------------------------------------------------------------------------- diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 680b01a28..d8c260a45 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -1825,6 +1825,14 @@ private: " if (0) { }\n" " THOU\n" "}"), InternalError); + ASSERT_NO_THROW(checkP("#define ONE if (0) { }\n" + "#define TEN ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE\n" + "#define HUN TEN TEN TEN TEN TEN TEN TEN TEN TEN TEN\n" + "#define THOU HUN HUN HUN HUN HUN HUN HUN HUN HUN HUN\n" + "void foo() {\n" + " if (0) { }\n" + " THOU\n" + "}")); } };