fix #2904 (Memory leak not detected when creating a new class instance)
This commit is contained in:
parent
66d145ba1c
commit
270b2b1772
|
@ -88,7 +88,7 @@ bool CheckMemoryLeak::isclass(const Tokenizer *_tokenizer, const Token *tok) con
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// return false if the type is a simple struct without member functions
|
// 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());
|
const Token *tok2 = Token::findmatch(_tokenizer->tokens(), pattern.c_str());
|
||||||
if (tok2)
|
if (tok2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2162,16 +2162,7 @@ void CheckOther::functionVariableUsage()
|
||||||
// is it a user defined type?
|
// is it a user defined type?
|
||||||
if (!start->tokAt(3)->isStandardType())
|
if (!start->tokAt(3)->isStandardType())
|
||||||
{
|
{
|
||||||
// lookup the type
|
if (!isRecordTypeWithoutSideEffects(start))
|
||||||
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)
|
|
||||||
allocate = false;
|
allocate = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,6 +233,7 @@ private:
|
||||||
TEST_CASE(func22); // Ticket #2668
|
TEST_CASE(func22); // Ticket #2668
|
||||||
TEST_CASE(func23); // Ticket #2667
|
TEST_CASE(func23); // Ticket #2667
|
||||||
TEST_CASE(func24); // Ticket #2705
|
TEST_CASE(func24); // Ticket #2705
|
||||||
|
TEST_CASE(func25); // Ticket #2904
|
||||||
|
|
||||||
TEST_CASE(allocfunc1);
|
TEST_CASE(allocfunc1);
|
||||||
TEST_CASE(allocfunc2);
|
TEST_CASE(allocfunc2);
|
||||||
|
@ -2219,6 +2220,24 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
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()
|
void allocfunc1()
|
||||||
{
|
{
|
||||||
check("static char *a()\n"
|
check("static char *a()\n"
|
||||||
|
|
|
@ -96,7 +96,8 @@ private:
|
||||||
TEST_CASE(localvaralias10); // ticket #2004
|
TEST_CASE(localvaralias10); // ticket #2004
|
||||||
TEST_CASE(localvarasm);
|
TEST_CASE(localvarasm);
|
||||||
TEST_CASE(localvarstatic);
|
TEST_CASE(localvarstatic);
|
||||||
TEST_CASE(localvardynamic);
|
TEST_CASE(localvardynamic1);
|
||||||
|
TEST_CASE(localvardynamic2); // ticket #2904
|
||||||
TEST_CASE(localvararray1); // ticket #2780
|
TEST_CASE(localvararray1); // ticket #2780
|
||||||
TEST_CASE(localvarstring);
|
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());
|
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"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -2774,6 +2775,111 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
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()
|
void localvararray1()
|
||||||
{
|
{
|
||||||
functionVariableUsage("void foo() {\n"
|
functionVariableUsage("void foo() {\n"
|
||||||
|
|
Loading…
Reference in New Issue