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())
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<unsigned int> notzero)
std::set<unsigned int> 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<unsigned int, VarInfo::AllocInfo> &alloctype = varInfo->alloctype;
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);
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();

View File

@ -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<unsigned int> notzero);
std::set<unsigned int> 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;
};
/// @}
//---------------------------------------------------------------------------

View File

@ -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"
"}"));
}
};