Fix recursiveCount in CheckLeakAutoVar to really be recursive count. (#1988)
This commit is contained in:
parent
f9bd589abb
commit
526a86dc60
|
@ -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();
|
||||||
|
|
|
@ -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;
|
|
||||||
};
|
};
|
||||||
/// @}
|
/// @}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -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"
|
||||||
|
"}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue