diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index cbb7bd954..a53a06d5b 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -75,10 +75,18 @@ bool CheckMemoryLeak::isclass(const Tokenizer *_tokenizer, const Token *tok) con if (tok->isStandardType()) return false; - std::ostringstream pattern; - pattern << "struct " << tok->str(); - if (Token::findmatch(_tokenizer->tokens(), pattern.str().c_str())) - return false; + // return false if the type is a simple struct without member functions + const std::string pattern("struct " + tok->str() + " {"); + const Token *tok2 = Token::findmatch(_tokenizer->tokens(), pattern.c_str()); + if (tok2) + { + while (tok2 && tok2->str() != "}" && tok2->str() != "(") + tok2 = tok2->next(); + + // Simple struct => return false + if (tok2 && tok2->str() == "}") + return false; + } return true; } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 4fbf3832b..c23d64395 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -285,6 +285,7 @@ private: // detect leak in class member function.. TEST_CASE(class1); + TEST_CASE(class2); TEST_CASE(autoptr1); TEST_CASE(if_with_and); @@ -2518,6 +2519,37 @@ private: ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: p\n", errout.str()); } + void class2() + { + check("class Fred {\n" + "public:\n" + " Fred() : rootNode(0) {}\n" + "\n" + "private:\n" + " struct Node {\n" + " Node(Node* p) {\n" + " parent = p;\n" + " if (parent) {\n" + " parent->children.append(this);\n" + " }\n" + " }\n" + "\n" + " ~Node() {\n" + " qDeleteAll(children);\n" + " }\n" + "\n" + " QList children;\n" + " };\n" + "\n" + " Node rootNode;\n" + "\n" + " void f() {\n" + " Node* recordNode = new Node(&rootNode);\n" + " }\n" + "};"); + ASSERT_EQUALS("", errout.str()); + } + void autoptr1() {