diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index f7aa4ce45..d8533aa4a 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -3199,6 +3199,14 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Token * const vartok deallocated = true; break; } + + // Linux kernel list + if (Token::Match(tok4, "[(,] & %varid% . %var% [,)]", structid)) + { + /** @todo check if the function deallocates the memory */ + deallocated = true; + break; + } } if (deallocated) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 3d31079de..71080f83f 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -4982,6 +4982,7 @@ private: TEST_CASE(function1); // Deallocating in function TEST_CASE(function2); // #2848: Taking address in function + TEST_CASE(function3); // #3024: kernel list // Handle if-else TEST_CASE(ifelse); @@ -5176,6 +5177,17 @@ private: ASSERT_EQUALS("", errout.str()); } + // #3024: kernel list + void function3() + { + check("void f() {\n" + " struct ABC *abc = kmalloc(100);\n" + " abc.a = (char *) kmalloc(10);\n" + " list_add_tail(&abc->list, head);\n" + "}\n", "test.c"); + ASSERT_EQUALS("", errout.str()); + } + void ifelse() { check("static void foo()\n"