Fixed #1856 (false positive: "pData" nulled but not freed upon failure)
This commit is contained in:
parent
7842658cb4
commit
9ffd06ff5e
|
@ -2186,11 +2186,32 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string
|
||||||
void CheckMemoryLeakInFunction::checkReallocUsage()
|
void CheckMemoryLeakInFunction::checkReallocUsage()
|
||||||
{
|
{
|
||||||
const Token *tok = _tokenizer->tokens();
|
const Token *tok = _tokenizer->tokens();
|
||||||
for (; tok; tok = tok->next())
|
while ((tok = Token::findmatch(tok, ") const| {")))
|
||||||
{
|
{
|
||||||
if (Token::Match(tok, "%var% = realloc|g_try_realloc ( %var% ,"))
|
// Record the varid's of the function parameters
|
||||||
|
std::set<unsigned int> parameterVarIds;
|
||||||
|
for (tok = tok->link(); tok && tok->str() != "{"; tok = tok->next())
|
||||||
{
|
{
|
||||||
if (tok->varId() == tok->tokAt(4)->varId())
|
if (tok->varId() != 0)
|
||||||
|
parameterVarIds.insert(tok->varId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for the "var = realloc(var, 100);" pattern within this function
|
||||||
|
unsigned int indentlevel = 0;
|
||||||
|
for (tok = tok->next(); tok; tok = tok->next())
|
||||||
|
{
|
||||||
|
if (tok->str() == "{")
|
||||||
|
++indentlevel;
|
||||||
|
else if (tok->str() == "}")
|
||||||
|
{
|
||||||
|
if (indentlevel == 0)
|
||||||
|
break;
|
||||||
|
--indentlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Token::Match(tok, "%var% = realloc|g_try_realloc ( %var% ,") &&
|
||||||
|
tok->varId() == tok->tokAt(4)->varId() &&
|
||||||
|
parameterVarIds.find(tok->varId()) == parameterVarIds.end())
|
||||||
{
|
{
|
||||||
memleakUponReallocFailureError(tok, tok->str());
|
memleakUponReallocFailureError(tok, tok->str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,6 +329,7 @@ private:
|
||||||
TEST_CASE(realloc4);
|
TEST_CASE(realloc4);
|
||||||
TEST_CASE(realloc5);
|
TEST_CASE(realloc5);
|
||||||
TEST_CASE(realloc6);
|
TEST_CASE(realloc6);
|
||||||
|
TEST_CASE(realloc7);
|
||||||
|
|
||||||
TEST_CASE(assign);
|
TEST_CASE(assign);
|
||||||
|
|
||||||
|
@ -2012,6 +2013,21 @@ private:
|
||||||
ASSERT_EQUALS(";;alloc;", getcode("char *buf; buf=realloc(0,100);", "buf"));
|
ASSERT_EQUALS(";;alloc;", getcode("char *buf; buf=realloc(0,100);", "buf"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void realloc7()
|
||||||
|
{
|
||||||
|
check("bool foo(size_t nLen, char* pData)\n"
|
||||||
|
"{\n"
|
||||||
|
" pData = (char*) realloc(pData, sizeof(char) + (nLen + 1)*sizeof(char));\n"
|
||||||
|
" if ( pData == NULL )\n"
|
||||||
|
" {\n"
|
||||||
|
" return false;\n"
|
||||||
|
" }\n"
|
||||||
|
" free(pData);\n"
|
||||||
|
" return true;\n"
|
||||||
|
"}\n", false);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void assign()
|
void assign()
|
||||||
{
|
{
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
|
|
Loading…
Reference in New Issue