Fixed #933 (Leaks with struct members not detected)
This commit is contained in:
parent
2bc67d72c2
commit
548dd42aaf
|
@ -2589,7 +2589,9 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Struct member is allocated => check if it is also properly deallocated..
|
// Struct member is allocated => check if it is also properly deallocated..
|
||||||
else if (Token::Match(tok2->previous(), "[;{}] %varid% . %var% = malloc|strdup|kmalloc (", variable->varId())) {
|
else if (Token::Match(tok2->previous(), "[;{}] %varid% . %var% = malloc|strdup|kmalloc (", variable->varId())
|
||||||
|
|| Token::Match(tok2->previous(), "[;{}] %varid% . %var% = new ", variable->varId())
|
||||||
|
|| Token::Match(tok2->previous(), "[;{}] %varid% . %var% = fopen (", variable->varId())) {
|
||||||
const unsigned int structid(variable->varId());
|
const unsigned int structid(variable->varId());
|
||||||
const unsigned int structmemberid(tok2->tokAt(2)->varId());
|
const unsigned int structmemberid(tok2->tokAt(2)->varId());
|
||||||
|
|
||||||
|
@ -2608,7 +2610,10 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deallocating the struct member..
|
// Deallocating the struct member..
|
||||||
else if (Token::Match(tok3, "free|kfree ( %var% . %varid% )", structmemberid)) {
|
else if (Token::Match(tok3, "free|kfree ( %var% . %varid% )", structmemberid)
|
||||||
|
|| Token::Match(tok3, "delete %var% . %varid%", structmemberid)
|
||||||
|
|| Token::Match(tok3, "delete [ ] %var% . %varid%", structmemberid)
|
||||||
|
|| Token::Match(tok3, "fclose ( %var% . %varid%", structmemberid)) {
|
||||||
// If the deallocation happens at the base level, don't check this member anymore
|
// If the deallocation happens at the base level, don't check this member anymore
|
||||||
if (indentlevel3 == 0)
|
if (indentlevel3 == 0)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -5079,7 +5079,7 @@ private:
|
||||||
TEST_CASE(globalvar);
|
TEST_CASE(globalvar);
|
||||||
|
|
||||||
// local struct variable
|
// local struct variable
|
||||||
TEST_CASE(localvar);
|
TEST_CASE(localvars);
|
||||||
}
|
}
|
||||||
|
|
||||||
void err() {
|
void err() {
|
||||||
|
@ -5323,16 +5323,50 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar() {
|
// Ticket #933 Leaks with struct members not detected
|
||||||
const char code[] = "void foo() {\n"
|
void localvars() {
|
||||||
" struct ABC abc;\n"
|
// Test error case
|
||||||
" abc.a = malloc(10);\n"
|
const char code_err[] = "struct A {\n"
|
||||||
"}\n";
|
" FILE* f;\n"
|
||||||
|
" char* c;\n"
|
||||||
|
" void* m;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"void func() {\n"
|
||||||
|
" struct A a;\n"
|
||||||
|
" a.f = fopen(\"test\", \"r\");\n"
|
||||||
|
" a.c = new char[12];\n"
|
||||||
|
" a.m = malloc(12);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
check(code, "test.cpp");
|
check(code_err, "test.cpp");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
check(code_err, "test.c");
|
||||||
|
ASSERT_EQUALS("[test.c:12]: (error) Memory leak: a.f\n"
|
||||||
|
"[test.c:12]: (error) Memory leak: a.c\n"
|
||||||
|
"[test.c:12]: (error) Memory leak: a.m\n", errout.str());
|
||||||
|
|
||||||
|
// Test OK case
|
||||||
|
const char code_ok[] = "struct A {\n"
|
||||||
|
" FILE* f;\n"
|
||||||
|
" char* c;\n"
|
||||||
|
" void* m;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"void func() {\n"
|
||||||
|
" struct A a;\n"
|
||||||
|
" a.f = fopen(\"test\", \"r\");\n"
|
||||||
|
" a.c = new char[12];\n"
|
||||||
|
" a.m = malloc(12);\n"
|
||||||
|
" fclose(a.f);\n"
|
||||||
|
" delete [] a.c;\n"
|
||||||
|
" free(a.m);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
check(code_ok, "test.cpp");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
check(code_ok, "test.c");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
check(code, "test.c");
|
|
||||||
ASSERT_EQUALS("[test.c:4]: (error) Memory leak: abc.a\n", errout.str());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue