fix #2971 (Wrong warning generated)

This commit is contained in:
Robert Reif 2011-08-06 19:10:15 -04:00
parent d23fb873cc
commit 222ed6d375
3 changed files with 52 additions and 12 deletions

View File

@ -159,14 +159,14 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
return gMalloc;
}
if (Token::Match(tok2, "new %type% [;()]") ||
Token::Match(tok2, "new ( std :: nothrow ) %type% [;()]") ||
Token::Match(tok2, "new ( nothrow ) %type% [;()]"))
if (Token::Match(tok2, "new struct| %type% [;()]") ||
Token::Match(tok2, "new ( std :: nothrow ) struct| %type% [;()]") ||
Token::Match(tok2, "new ( nothrow ) struct| %type% [;()]"))
return New;
if (Token::Match(tok2, "new %type% [") ||
Token::Match(tok2, "new ( std :: nothrow ) %type% [") ||
Token::Match(tok2, "new ( nothrow ) %type% ["))
if (Token::Match(tok2, "new struct| %type% [") ||
Token::Match(tok2, "new ( std :: nothrow ) struct| %type% [") ||
Token::Match(tok2, "new ( nothrow ) struct| %type% ["))
return NewArray;
if (Token::Match(tok2, "fopen|tmpfile|g_fopen ("))
@ -1035,23 +1035,26 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
// don't check classes..
if (alloc == CheckMemoryLeak::New)
{
if (Token::Match(tok->tokAt(2), "new %type% [(;]"))
if (Token::Match(tok->tokAt(2), "new struct| %type% [(;]"))
{
if (isclass(_tokenizer, tok->tokAt(3), varid))
const int offset = tok->strAt(3) == "struct" ? 1 : 0;
if (isclass(_tokenizer, tok->tokAt(3 + offset), varid))
{
alloc = No;
}
}
else if (Token::Match(tok->tokAt(2), "new ( nothrow ) %type%"))
else if (Token::Match(tok->tokAt(2), "new ( nothrow ) struct| %type%"))
{
if (isclass(_tokenizer, tok->tokAt(6), varid))
const int offset = tok->strAt(6) == "struct" ? 1 : 0;
if (isclass(_tokenizer, tok->tokAt(6 + offset), varid))
{
alloc = No;
}
}
else if (Token::Match(tok->tokAt(2), "new ( std :: nothrow ) %type%"))
else if (Token::Match(tok->tokAt(2), "new ( std :: nothrow ) struct| %type%"))
{
if (isclass(_tokenizer, tok->tokAt(8), varid))
const int offset = tok->strAt(8) == "struct" ? 1 : 0;
if (isclass(_tokenizer, tok->tokAt(8 + offset), varid))
{
alloc = No;
}

View File

@ -2510,6 +2510,13 @@ bool Tokenizer::tokenize(std::istream &code,
}
}
// convert Microsoft DEBUG_NEW macro to new
for (Token *tok = _tokens; tok; tok = tok->next())
{
if (tok->str() == "DEBUG_NEW")
tok->str("new");
}
// typedef..
simplifyTypedef();

View File

@ -971,6 +971,21 @@ private:
" Fred *f = new(std::nothrow) Fred;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
// ticket #2971
check("void f()\n"
"{\n"
" Fred *f = new(std::nothrow) Fred[10];\n"
" delete f;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Mismatching allocation and deallocation: f\n", errout.str());
check("void f()\n"
"{\n"
" struct Fred *f = new(std::nothrow) struct Fred[10];\n"
" delete f;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Mismatching allocation and deallocation: f\n", errout.str());
}
@ -1388,6 +1403,21 @@ private:
" free(a);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:4]: (error) Mismatching allocation and deallocation: a\n", errout.str());
// ticket #2971
check("void f()\n"
"{\n"
" Fred *a = new Fred[10];\n"
" free(a);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:4]: (error) Mismatching allocation and deallocation: a\n", errout.str());
check("void f()\n"
"{\n"
" struct Fred *a = new struct Fred[10];\n"
" free(a);\n"
"}\n", true);
ASSERT_EQUALS("[test.cpp:4]: (error) Mismatching allocation and deallocation: a\n", errout.str());
}
void mismatch2()