Fixed ticket #367 (Deallocating a deallocated pointer false positive when va_list used)

The overall matching of functions when calls are made were improved.
This commit is contained in:
Daniel Marjamäki 2009-06-12 17:31:29 +02:00
parent 6362574c1a
commit 777790ebc7
2 changed files with 54 additions and 1 deletions

View File

@ -280,6 +280,33 @@ bool CheckMemoryLeakInFunction::notvar(const Token *tok, const char *varnames[],
} }
static int countParameters(const Token *tok)
{
if (!Token::Match(tok, "%var% ("))
return -1;
if (Token::Match(tok->tokAt(2), "void| )"))
return 0;
int numpar = 1;
int parlevel = 0;
for (; tok; tok = tok->next())
{
if (tok->str() == "(")
++parlevel;
else if (tok->str() == ")")
{
if (parlevel <= 1)
return numpar;
--parlevel;
}
else if (parlevel == 1 && tok->str() == ",")
++numpar;
}
return -1;
}
const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<const Token *> callstack, const char *varnames[], AllocType &alloctype, AllocType &dealloctype, bool &all, unsigned int sz) const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<const Token *> callstack, const char *varnames[], AllocType &alloctype, AllocType &dealloctype, bool &all, unsigned int sz)
{ {
@ -328,6 +355,11 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
} }
callstack.push_back(tok); callstack.push_back(tok);
// how many parameters is there in the function call?
int numpar = countParameters(tok);
if (numpar <= 0)
return "callfunc";
int par = 1; int par = 1;
int parlevel = 0; int parlevel = 0;
std::string pattern = "[,()] "; std::string pattern = "[,()] ";
@ -361,6 +393,11 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
if (Token::Match(tok, pattern.c_str())) if (Token::Match(tok, pattern.c_str()))
{ {
const Token *ftok = _tokenizer->GetFunctionTokenByName(funcname.c_str()); const Token *ftok = _tokenizer->GetFunctionTokenByName(funcname.c_str());
// how many parameters does the function want?
if (numpar != countParameters(ftok))
return "recursive";
const char *parname = Tokenizer::getParameterName(ftok, par); const char *parname = Tokenizer::getParameterName(ftok, par);
if (! parname) if (! parname)
return "recursive"; return "recursive";

View File

@ -143,6 +143,7 @@ private:
TEST_CASE(func11); // Bug 2458510 - Function pointer TEST_CASE(func11); // Bug 2458510 - Function pointer
TEST_CASE(func12); TEST_CASE(func12);
TEST_CASE(func13); TEST_CASE(func13);
TEST_CASE(func14);
TEST_CASE(throw1); TEST_CASE(throw1);
TEST_CASE(throw2); TEST_CASE(throw2);
@ -1340,7 +1341,22 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void func14()
{
// It is not known what the "foo" that only takes one parameter does..
check("static void foo(char *a, char *b)\n"
"{\n"
" free(a);\n"
" free(b);\n"
"}\n"
"static void f()\n"
"{\n"
" char *p = malloc(100);\n"
" foo(p);\n"
" free(p);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
/* /*