fix #2904 (Memory leak not detected when creating a new class instance)

This commit is contained in:
Robert Reif 2011-07-14 19:15:59 -04:00
parent 66d145ba1c
commit 270b2b1772
4 changed files with 129 additions and 13 deletions

View File

@ -88,7 +88,7 @@ bool CheckMemoryLeak::isclass(const Tokenizer *_tokenizer, const Token *tok) con
return false;
// return false if the type is a simple struct without member functions
const std::string pattern("struct " + tok->str() + " {");
const std::string pattern("struct|class " + tok->str() + " {");
const Token *tok2 = Token::findmatch(_tokenizer->tokens(), pattern.c_str());
if (tok2)
{

View File

@ -2162,16 +2162,7 @@ void CheckOther::functionVariableUsage()
// is it a user defined type?
if (!start->tokAt(3)->isStandardType())
{
// lookup the type
const Scope *type = symbolDatabase->findVariableType(&(*scope), start->tokAt(3));
// unknown type?
if (!type)
allocate = false;
// has default constructor or
// has members with unknown type or default constructor
else if (type->needInitialization == Scope::False)
if (!isRecordTypeWithoutSideEffects(start))
allocate = false;
}
}

View File

@ -233,6 +233,7 @@ private:
TEST_CASE(func22); // Ticket #2668
TEST_CASE(func23); // Ticket #2667
TEST_CASE(func24); // Ticket #2705
TEST_CASE(func25); // Ticket #2904
TEST_CASE(allocfunc1);
TEST_CASE(allocfunc2);
@ -2219,6 +2220,24 @@ private:
ASSERT_EQUALS("", errout.str());
}
void func25() // ticket #2904
{
check("class Fred { };\n"
"void f(void) \n"
"{\n"
" Fred *f = new Fred();\n"
" delete f;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("class Fred { };\n"
"void f(void) \n"
"{\n"
" Fred *f = new Fred();\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: f\n", errout.str());
}
void allocfunc1()
{
check("static char *a()\n"

View File

@ -96,7 +96,8 @@ private:
TEST_CASE(localvaralias10); // ticket #2004
TEST_CASE(localvarasm);
TEST_CASE(localvarstatic);
TEST_CASE(localvardynamic);
TEST_CASE(localvardynamic1);
TEST_CASE(localvardynamic2); // ticket #2904
TEST_CASE(localvararray1); // ticket #2780
TEST_CASE(localvarstring);
@ -2670,7 +2671,7 @@ private:
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used\n", errout.str());
}
void localvardynamic()
void localvardynamic1()
{
functionVariableUsage("void foo()\n"
"{\n"
@ -2774,6 +2775,111 @@ private:
ASSERT_EQUALS("", errout.str());
}
void localvardynamic2()
{
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = malloc(sizeof(Fred));\n"
" free(ptr);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used\n", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = malloc(sizeof(Fred));\n"
" ptr->i = 0;\n"
" free(ptr);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" struct Fred* ptr = malloc(sizeof(Fred));\n"
" free(ptr);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used\n", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" struct Fred* ptr = malloc(sizeof(Fred));\n"
" ptr->i = 0;\n"
" free(ptr);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = new Fred();\n"
" delete ptr;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used\n", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = new Fred();\n"
" ptr->i = 0;\n"
" delete ptr;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" struct Fred* ptr = new Fred();\n"
" free(ptr);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used\n", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" struct Fred* ptr = new Fred();\n"
" ptr->i = 0;\n"
" free(ptr);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class Fred { public: int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = malloc(sizeof(Fred));\n"
" free(ptr);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used\n", errout.str());
functionVariableUsage("class Fred { public: int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = malloc(sizeof(Fred));\n"
" ptr->i = 0;\n"
" free(ptr);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class Fred { public: int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = new Fred();\n"
" delete ptr;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used\n", errout.str());
functionVariableUsage("class Fred { public: int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = new Fred();\n"
" ptr->i = 0;\n"
" delete ptr;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void localvararray1()
{
functionVariableUsage("void foo() {\n"