diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 0f56c03c6..1cd59bace 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2641,6 +2641,8 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var // struct assignment.. else if (Token::Match(tok3, "= %varid% ;", structid)) { break; + } else if (Token::Match(tok3, "= %var% . %varid% ;", structmemberid)) { + break; } // goto isn't handled well.. bail out even though there might be leaks diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index bd9cba5dd..f56587032 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -4960,6 +4960,9 @@ private: // Handle if-else TEST_CASE(ifelse); + // Linked list + TEST_CASE(linkedlist); + // struct variable is a global variable TEST_CASE(globalvar); @@ -5180,6 +5183,21 @@ private: ASSERT_EQUALS("", errout.str()); } + void linkedlist() { + check("static void foo() {\n" + " struct ABC *abc = malloc(sizeof(struct ABC));\n" + " abc->next = malloc(sizeof(struct ABC));\n" + " abc->next->next = NULL;\n" + "\n" + " while (abc) {\n" + " struct ABC *next = abc->next;\n" + " free(abc);\n" + " abc = next;\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void globalvar() { check("struct ABC *abc;\n" "\n"