#8126 Fix previous commit (#3833)

* Fix #8126 unsafeClassCanLeak missing for array of pointers

* #8126 Fix previous commit

* Format

* Format
This commit is contained in:
chrchr-github 2022-02-15 20:03:02 +01:00 committed by GitHub
parent e7e2439347
commit 907218254e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 5 deletions

View File

@ -592,7 +592,7 @@ void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarnam
} }
// Allocate.. // Allocate..
if (!body || Token::Match(tok, "%varid% =", varid)) { if (!body || Token::Match(tok, "%varid% =|[", varid)) {
// var1 = var2 = ... // var1 = var2 = ...
// bail out // bail out
if (tok->strAt(-1) == "=") if (tok->strAt(-1) == "=")
@ -604,7 +604,11 @@ void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarnam
tok->strAt(-2) != scope->className) tok->strAt(-2) != scope->className)
return; return;
AllocType alloc = getAllocationType(tok->tokAt(body ? 2 : 3), 0); const Token* allocTok = tok->tokAt(body ? 2 : 3);
if (tok->astParent() && tok->astParent()->str() == "[" && tok->astParent()->astParent())
allocTok = tok->astParent()->astParent()->astOperand2();
AllocType alloc = getAllocationType(allocTok, 0);
if (alloc != CheckMemoryLeak::No) { if (alloc != CheckMemoryLeak::No) {
if (constructor) if (constructor)
allocInConstructor = true; allocInConstructor = true;

View File

@ -84,6 +84,7 @@ private:
TEST_CASE(copyConstructor3); // defaulted/deleted TEST_CASE(copyConstructor3); // defaulted/deleted
TEST_CASE(copyConstructor4); // base class with private constructor TEST_CASE(copyConstructor4); // base class with private constructor
TEST_CASE(copyConstructor5); // multiple inheritance TEST_CASE(copyConstructor5); // multiple inheritance
TEST_CASE(copyConstructor6); // array of pointers
TEST_CASE(noOperatorEq); // class with memory management should have operator eq TEST_CASE(noOperatorEq); // class with memory management should have operator eq
TEST_CASE(noDestructor); // class with memory management should have destructor TEST_CASE(noDestructor); // class with memory management should have destructor
@ -967,6 +968,21 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void copyConstructor6() {
checkCopyConstructor("struct S {\n"
" S() {\n"
" for (int i = 0; i < 5; i++)\n"
" a[i] = new char[3];\n"
" }\n"
" char* a[5];\n"
"};\n");
TODO_ASSERT_EQUALS("[test.cpp:4]: (warning) Struct 'S' does not have a copy constructor which is recommended since it has dynamic memory/resource allocation(s).\n"
"[test.cpp:4]: (warning) Struct 'S' does not have a operator= which is recommended since it has dynamic memory/resource allocation(s).\n"
"[test.cpp:4]: (warning) Struct 'S' does not have a destructor which is recommended since it has dynamic memory/resource allocation(s).\n",
"",
errout.str());
}
void noOperatorEq() { void noOperatorEq() {
checkCopyConstructor("struct F {\n" checkCopyConstructor("struct F {\n"
" char* c;\n" " char* c;\n"

View File

@ -1465,10 +1465,10 @@ private:
void class27() { // ticket #8126 - array of pointers void class27() { // ticket #8126 - array of pointers
check("struct S {\n" check("struct S {\n"
" S() {\n" " S() {\n"
" for (int i = 0; i < 1; i++)\n" " for (int i = 0; i < 5; i++)\n"
" a = new char[3];\n" " a[i] = new char[3];\n"
" }\n" " }\n"
" char* a;\n" " char* a[5];\n"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:6]: (style) Class 'S' is unsafe, 'S::a' can leak by wrong usage.\n", errout.str()); ASSERT_EQUALS("[test.cpp:6]: (style) Class 'S' is unsafe, 'S::a' can leak by wrong usage.\n", errout.str());
} }