diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 0ae71282e..de177d953 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -725,7 +725,9 @@ void CheckMemoryLeakStructMember::check() const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Variable* var : symbolDatabase->variableList()) { - if (!var || (!var->isLocal() && !(var->isArgument() && var->scope())) || var->isStatic() || var->isReference()) + if (!var || (!var->isLocal() && !(var->isArgument() && var->scope())) || var->isStatic()) + continue; + if (var->isReference() || (var->valueType() && var->valueType()->pointer > 1)) continue; if (var->typeEndToken()->isStandardType()) continue; @@ -752,7 +754,7 @@ bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const variable) { // Is struct variable a pointer? - if (variable->isPointer()) { + if (variable->isArrayOrPointer()) { // Check that variable is allocated with malloc if (!isMalloc(variable)) return; diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 7dd1492c8..1f67449b7 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -1930,6 +1930,22 @@ private: " s->a[e] = strdup(n);\n" "}\n", false); ASSERT_EQUALS("", errout.str()); + + check("void f(struct S** s, const char* c) {\n" + " *s = malloc(sizeof(struct S));\n" + " (*s)->value = strdup(c);\n" + "}\n", false); + ASSERT_EQUALS("", errout.str()); + + check("struct S {\n" + " size_t mpsz;\n" + " void* hdr;\n" + "};\n" + "void f(struct S s[static 1U], int fd, size_t size) {\n" + " s->mpsz = size;\n" + " s->hdr = mmap(NULL, s->mpsz, PROT_READ, MAP_SHARED, fd, 0);\n" + "}\n", false); + ASSERT_EQUALS("", errout.str()); } void failedAllocation() {