Fix recursiveCount in CheckLeakAutoVar to really be recursive count. (#1988)

This commit is contained in:
IOBYTE 2019-07-13 01:40:24 -04:00 committed by Daniel Marjamäki
parent f9bd589abb
commit 526a86dc60
3 changed files with 20 additions and 14 deletions

View File

@ -159,12 +159,10 @@ void CheckLeakAutoVar::check()
if (scope->hasInlineOrLambdaFunction()) if (scope->hasInlineOrLambdaFunction())
continue; continue;
recursiveCount = 0;
// Empty variable info // Empty variable info
VarInfo varInfo; VarInfo varInfo;
checkScope(scope->bodyStart, &varInfo, notzero); checkScope(scope->bodyStart, &varInfo, notzero, 0);
varInfo.conditionalAlloc.clear(); varInfo.conditionalAlloc.clear();
@ -236,12 +234,13 @@ static const Token * isFunctionCall(const Token * nameToken)
void CheckLeakAutoVar::checkScope(const Token * const startToken, void CheckLeakAutoVar::checkScope(const Token * const startToken,
VarInfo *varInfo, VarInfo *varInfo,
std::set<unsigned int> notzero) std::set<unsigned int> notzero,
unsigned int recursiveCount)
{ {
// The C++ standard suggests a minimum of 256 nested control statements // 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. // but MSVC has a limit of 100.
if (++recursiveCount > 384) if (++recursiveCount > 100)
throw InternalError(startToken, "Internal limit: CheckLeakAutoVar::checkScope() Maximum recursive count of 384 reached.", InternalError::LIMIT); throw InternalError(startToken, "Internal limit: CheckLeakAutoVar::checkScope() Maximum recursive count of 100 reached.", InternalError::LIMIT);
std::map<unsigned int, VarInfo::AllocInfo> &alloctype = varInfo->alloctype; std::map<unsigned int, VarInfo::AllocInfo> &alloctype = varInfo->alloctype;
std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage; std::map<unsigned int, std::string> &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); closingParenthesis = closingParenthesis->linkAt(1);
if (Token::simpleMatch(closingParenthesis, "} else {")) { if (Token::simpleMatch(closingParenthesis, "} else {")) {
checkScope(closingParenthesis->tokAt(2), &varInfo2, notzero); checkScope(closingParenthesis->tokAt(2), &varInfo2, notzero, recursiveCount);
tok = closingParenthesis->linkAt(2)->previous(); tok = closingParenthesis->linkAt(2)->previous();
} else { } else {
tok = closingParenthesis->previous(); tok = closingParenthesis->previous();

View File

@ -95,12 +95,12 @@ public:
class CPPCHECKLIB CheckLeakAutoVar : public Check { class CPPCHECKLIB CheckLeakAutoVar : public Check {
public: public:
/** This constructor is used when registering the CheckLeakAutoVar */ /** This constructor is used when registering the CheckLeakAutoVar */
CheckLeakAutoVar() : Check(myName()), recursiveCount(0) { CheckLeakAutoVar() : Check(myName()) {
} }
/** This constructor is used when running checks. */ /** This constructor is used when running checks. */
CheckLeakAutoVar(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) 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 { void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) OVERRIDE {
@ -116,7 +116,8 @@ private:
/** check for leaks in a function scope */ /** check for leaks in a function scope */
void checkScope(const Token * const startToken, void checkScope(const Token * const startToken,
VarInfo *varInfo, VarInfo *varInfo,
std::set<unsigned int> notzero); std::set<unsigned int> notzero,
unsigned int recursiveCount);
/** Check token inside expression. /** Check token inside expression.
* @param tok token inside expression. * @param tok token inside expression.
@ -163,8 +164,6 @@ private:
std::string classInfo() const OVERRIDE { std::string classInfo() const OVERRIDE {
return "Detect when a auto variable is allocated but not deallocated or deallocated twice.\n"; return "Detect when a auto variable is allocated but not deallocated or deallocated twice.\n";
} }
unsigned int recursiveCount;
}; };
/// @} /// @}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -1825,6 +1825,14 @@ private:
" if (0) { }\n" " if (0) { }\n"
" THOU\n" " THOU\n"
"}"), InternalError); "}"), 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"
"}"));
} }
}; };