Fix #9253: leakNoVarFunctionCall: do not warn if freopen opens standard stream (#2076)

This fixes false positives from daca@home where freopen is used to
reopen a standard stream. There is no longer a warning for

	void f() {
		assert(freopen("/dev/null", "r", stdin));
	}
This commit is contained in:
Rikard Falkeborn 2019-08-12 12:53:59 +02:00 committed by Daniel Marjamäki
parent aadc404958
commit cd36f8ed0a
3 changed files with 27 additions and 8 deletions

View File

@ -259,6 +259,19 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getDeallocationType(const Token *tok
return No;
}
bool CheckMemoryLeak::isReopenStandardStream(const Token *tok) const
{
if (getReallocationType(tok, 0) == File) {
const Library::AllocFunc *f = mSettings_->library.getReallocFuncInfo(tok);
if (f && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(tok)) {
const Token* arg = getArguments(tok).at(f->reallocArg - 1);
if (Token::Match(arg, "stdin|stdout|stderr"))
return true;
}
}
return false;
}
//--------------------------------------------------------------------------
@ -979,6 +992,8 @@ void CheckMemoryLeakNoVar::check()
functionName == "fclose" ||
functionName == "realloc")
break;
if (isReopenStandardStream(tok->next()))
continue;
if (CheckMemoryLeakInFunction::test_white_list(functionName, mSettings, mTokenizer->isCPP())) {
functionCallLeak(tok, tok->strAt(1), functionName);
break;
@ -1006,14 +1021,8 @@ void CheckMemoryLeakNoVar::checkForUnusedReturnValue(const Scope *scope)
if (tok != tok->next()->astOperand1())
continue;
if (getReallocationType(tok, 0) == File) {
const Library::AllocFunc *f = mSettings->library.getReallocFuncInfo(tok);
if (f && f->reallocArg > 0 && f->reallocArg <= numberOfArguments(tok)) {
const Token* arg = getArguments(tok).at(f->reallocArg - 1);
if (Token::Match(arg, "stdin|stdout|stderr"))
continue;
}
}
if (isReopenStandardStream(tok))
continue;
// get ast parent, skip casts
const Token *parent = tok->next()->astParent();

View File

@ -114,6 +114,11 @@ public:
*/
AllocType getReallocationType(const Token *tok2, nonneg int varid) const;
/**
* Check if token reopens a standard stream
* @param tok token to check
*/
bool isReopenStandardStream(const Token *tok) const;
/**
* Report that there is a memory leak (new/malloc/etc)
* @param tok token where memory is leaked

View File

@ -2139,6 +2139,11 @@ private:
" 42, strcmp(strdup(a), b);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Allocation with strdup, strcmp doesn't release it.\n", errout.str());
check("void f() {\n"
" assert(freopen(\"/dev/null\", \"r\", stdin));\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void missingAssignment() {