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:
parent
6362574c1a
commit
777790ebc7
|
@ -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";
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue