Fixed #264 (Memory Leak: alloc by assigning to a return value)

The fix was inspired by the previous patch submitted by hoangtuansu
This commit is contained in:
Daniel Marjamäki 2009-06-15 17:44:59 +02:00
parent 195880807e
commit 433ff048a4
3 changed files with 107 additions and 32 deletions

View File

@ -252,7 +252,37 @@ void CheckMemoryLeak::mismatchAllocDealloc(const std::list<const Token *> &calls
error(callstack, "error", "mismatchAllocDealloc", "Mismatching allocation and deallocation: " + varname);
}
CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Token *tok) const
{
// Locate the start of the function..
unsigned int parlevel = 0;
while (tok)
{
if (tok->str() == "{" || tok->str() == "}")
return No;
if (tok->str() == "(")
{
if (parlevel != 0)
return No;
++parlevel;
}
else if (tok->str() == ")")
{
if (parlevel != 1)
return No;
if (Token::Match(tok, ") const| { return new %type% ; }"))
return New;
if (Token::Match(tok, ") const| { return new %type% [ %any% ] ; }"))
return NewArray;
break;
}
tok = tok->next();
}
return No;
}
@ -355,6 +385,14 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
}
callstack.push_back(tok);
// Check if this is a function that allocates memory..
{
const Token *ftok = _tokenizer->GetFunctionTokenByName(funcname.c_str());
AllocType a = functionReturnType(ftok);
if (a != No)
return "alloc";
}
// how many parameters is there in the function call?
int numpar = countParameters(tok);
if (numpar <= 0)

View File

@ -43,7 +43,7 @@ class Token;
class CheckMemoryLeak
{
protected:
public:
CheckMemoryLeak() { }
/** What type of allocation are used.. the "Many" means that several types of allocation and deallocation are used */
@ -68,6 +68,9 @@ protected:
// error message
virtual void error(const Token *tok, const std::string &severity, const std::string &id, const std::string &msg) = 0;
virtual void error(const std::list<const Token *> &callstack, const std::string &severity, const std::string &id, const std::string &msg) = 0;
/** What type of allocated memory does the given function return? */
AllocType functionReturnType(const Token *tok) const;
};

View File

@ -24,11 +24,61 @@
#include "../src/checkmemoryleak.h"
#include "testsuite.h"
#include <iostream>
#include <sstream>
extern std::ostringstream errout;
class TestMemleak : private TestFixture
{
public:
TestMemleak() : TestFixture("TestMemleak")
{ }
private:
void run()
{
TEST_CASE(testFunctionReturnType);
}
CheckMemoryLeak::AllocType functionReturnType(const char code[])
{
// Tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
return ((const CheckMemoryLeak *)0)->functionReturnType(tokenizer.tokens());
}
void testFunctionReturnType()
{
{
const char code[] = "const char *foo()\n"
"{ return 0; }";
ASSERT_EQUALS(CheckMemoryLeak::No, functionReturnType(code));
}
{
const char code[] = "Fred *newFred()\n"
"{ return new Fred; }";
ASSERT_EQUALS(CheckMemoryLeak::New, functionReturnType(code));
}
{
const char code[] = "char *foo()\n"
"{ return new char[100]; }";
ASSERT_EQUALS(CheckMemoryLeak::NewArray, functionReturnType(code));
}
}
};
static TestMemleak testMemleak;
class TestMemleakInFunction : public TestFixture
{
public:
@ -145,6 +195,8 @@ private:
TEST_CASE(func13);
TEST_CASE(func14);
TEST_CASE(allocfunc1);
TEST_CASE(throw1);
TEST_CASE(throw2);
@ -1366,38 +1418,20 @@ private:
}
/*
void func3()
{
check( "static char *dmalloc()\n"
"{\n"
" char *p = new char[100];\n"
" return p;\n"
"}\n"
"static void f()\n"
"{\n"
" char *p = dmalloc();\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:9]: Memory leak: p\n"), errout.str() );
}
void allocfunc1()
{
check("static char *a()\n"
"{\n"
" return new char[100];\n"
"}\n"
"static void b()\n"
"{\n"
" char *p = a();\n"
"}\n");
ASSERT_EQUALS(std::string("[test.cpp:8]: (error) Memory leak: p\n"), errout.str());
}
void func4()
{
check( "static char *dmalloc()\n"
"{\n"
" char *p = new char[100];\n"
" return p;\n"
"}\n"
"static void f()\n"
"{\n"
" char *p = dmalloc();\n"
" delete p;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:9]: Mismatching allocation and deallocation: p\n"), errout.str() );
}
*/