parent
413a5a4865
commit
8513fb81d2
|
@ -206,6 +206,30 @@ static bool isPointerReleased(const Token *startToken, const Token *endToken, no
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool checkVariable(const Token *varTok, const bool isCpp)
|
||||
{
|
||||
// not a local variable nor argument?
|
||||
const Variable *var = varTok->variable();
|
||||
if (var && !var->isArgument() && (!var->isLocal() || var->isStatic()))
|
||||
return false;
|
||||
|
||||
// Don't check reference variables
|
||||
if (var && var->isReference())
|
||||
return false;
|
||||
|
||||
// non-pod variable
|
||||
if (isCpp) {
|
||||
if (!var)
|
||||
return false;
|
||||
// Possibly automatically deallocated memory
|
||||
if (!var->typeStartToken()->isStandardType() && Token::Match(varTok, "%var% = new"))
|
||||
return false;
|
||||
if (!var->isPointer() && !var->typeStartToken()->isStandardType())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** checks if nameToken is a name of a function in a function call:
|
||||
* func(arg)
|
||||
* or
|
||||
|
@ -318,26 +342,9 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
|||
leakIfAllocated(varTok, *varInfo);
|
||||
varInfo->erase(varTok->varId());
|
||||
|
||||
// not a local variable nor argument?
|
||||
const Variable *var = varTok->variable();
|
||||
if (var && !var->isArgument() && (!var->isLocal() || var->isStatic()))
|
||||
if (!checkVariable(varTok, mTokenizer->isCPP()))
|
||||
continue;
|
||||
|
||||
// Don't check reference variables
|
||||
if (var && var->isReference())
|
||||
continue;
|
||||
|
||||
// non-pod variable
|
||||
if (mTokenizer->isCPP()) {
|
||||
if (!var)
|
||||
continue;
|
||||
// Possibly automatically deallocated memory
|
||||
if (!var->typeStartToken()->isStandardType() && Token::Match(varTok, "%var% = new"))
|
||||
continue;
|
||||
if (!var->isPointer() && !var->typeStartToken()->isStandardType())
|
||||
continue;
|
||||
}
|
||||
|
||||
// allocation?
|
||||
const Token *const fTok = tokRightAstOperand ? tokRightAstOperand->previous() : nullptr;
|
||||
if (Token::Match(fTok, "%type% (")) {
|
||||
|
@ -375,6 +382,9 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
|||
for (const Token *innerTok = tok->tokAt(2); innerTok && innerTok != closingParenthesis; innerTok = innerTok->next()) {
|
||||
// TODO: replace with checkTokenInsideExpression()
|
||||
|
||||
if (!checkVariable(innerTok, mTokenizer->isCPP()))
|
||||
continue;
|
||||
|
||||
if (Token::Match(innerTok, "%var% =") && innerTok->astParent() == innerTok->next()) {
|
||||
// allocation?
|
||||
// right ast part (after `=` operator)
|
||||
|
|
|
@ -121,6 +121,7 @@ private:
|
|||
TEST_CASE(ifelse12); // #8340 - if ((*p = malloc(4)) == NULL)
|
||||
TEST_CASE(ifelse13); // #8392
|
||||
TEST_CASE(ifelse14); // #9130 - if (x == (char*)NULL)
|
||||
TEST_CASE(ifelse15); // #9206 - if (global_ptr = malloc(1))
|
||||
|
||||
// switch
|
||||
TEST_CASE(switch1);
|
||||
|
@ -1364,6 +1365,23 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void ifelse15() { // #9206
|
||||
check("struct SSS { int a; };\n"
|
||||
"SSS* global_ptr;\n"
|
||||
"void test_alloc() {\n"
|
||||
" if ( global_ptr = new SSS()) {}\n"
|
||||
" return;\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("FILE* hFile;\n"
|
||||
"int openFile( void ) {\n"
|
||||
" if ((hFile = fopen(\"1.txt\", \"wb\" )) == NULL) return 0;\n"
|
||||
" return 1;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void switch1() {
|
||||
check("void f() {\n"
|
||||
" char *p = 0;\n"
|
||||
|
|
Loading…
Reference in New Issue