From 2e7b5ae2e8a5bed733faaf48e27e1ec6b055d522 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Tue, 14 Nov 2023 22:04:33 +0100 Subject: [PATCH 1/6] Fix #12186 FN memleak with outparam allocation --- lib/checkleakautovar.cpp | 13 ++++++++++--- test/testleakautovar.cpp | 9 ++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 0f562d65b95..5c77eebef46 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -968,10 +968,17 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin if (!isnull && (!af || af->arg == argNr)) { const Library::AllocFunc* deallocFunc = mSettings->library.getDeallocFuncInfo(tokName); VarInfo::AllocInfo dealloc(deallocFunc ? deallocFunc->groupId : 0, VarInfo::DEALLOC, tokName); - if (dealloc.type == 0) - changeAllocStatus(varInfo, allocation, tokName, arg); + if (const Library::AllocFunc* allocFunc = mSettings->library.getAllocFuncInfo(tokName)) { + if (allocFunc->arg == argNr) { + VarInfo::AllocInfo varAlloc = allocation; + varAlloc.type = allocFunc->groupId; + varAlloc.status = VarInfo::ALLOC; + varAlloc.allocTok = arg; + changeAllocStatus(varInfo, varAlloc, tokName, arg); + } + } else - changeAllocStatus(varInfo, dealloc, tokName, arg); + changeAllocStatus(varInfo, dealloc.type == 0 ? allocation : dealloc, tokName, arg); } } // Check smart pointer diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index a08bc2d649a..2ac0a356e60 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -3004,8 +3004,7 @@ class TestLeakAutoVarWindows : public TestFixture { " HeapFree(MyHeap, 0, a);" " HeapFree(MyHeap, 0, b);" "}"); - TODO_ASSERT_EQUALS("[test.c:1] (error) Resource leak: MyHeap", - "", errout.str()); + ASSERT_EQUALS("[test.c:1]: (error) Resource leak: MyHeap\n", errout.str()); check("void f() {" " HANDLE MyHeap = HeapCreate(0, 0, 0);" @@ -3013,9 +3012,9 @@ class TestLeakAutoVarWindows : public TestFixture { " int *b = HeapAlloc(MyHeap, 0, sizeof(int));" " HeapFree(MyHeap, 0, a);" "}"); - TODO_ASSERT_EQUALS("[test.c:1] (error) Memory leak: MyHeap\n" - "[test.c:1] (error) Memory leak: b", - "[test.c:1]: (error) Memory leak: b\n", errout.str()); + ASSERT_EQUALS("[test.c:1]: (error) Resource leak: MyHeap\n" + "[test.c:1]: (error) Memory leak: b\n", + errout.str()); } }; From 3477dbecc02d8e90d6cf40f98062225fa5f63720 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Tue, 14 Nov 2023 22:06:42 +0100 Subject: [PATCH 2/6] Add test --- test/cfg/gnu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/cfg/gnu.c b/test/cfg/gnu.c index 89c060258dd..8b2f84ac6f8 100644 --- a/test/cfg/gnu.c +++ b/test/cfg/gnu.c @@ -359,6 +359,12 @@ void memleak_asprintf(char **ptr, const char *fmt, const int arg) } } +void memleak_asprintf2() { // #12186 + char* p = malloc(5); + // cppcheck-suppress memleak + (void)asprintf(&p, "%s", "test"); +} + void memleak_xmalloc() { char *p = (char*)xmalloc(10); From be7e4a82c9070773cc5f8935dc9a72c4c7b7431a Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Tue, 14 Nov 2023 22:27:34 +0100 Subject: [PATCH 3/6] changeAllocStatus() doesn't allocate --- lib/checkleakautovar.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 5c77eebef46..991fb1b1891 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -970,11 +970,10 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin VarInfo::AllocInfo dealloc(deallocFunc ? deallocFunc->groupId : 0, VarInfo::DEALLOC, tokName); if (const Library::AllocFunc* allocFunc = mSettings->library.getAllocFuncInfo(tokName)) { if (allocFunc->arg == argNr) { - VarInfo::AllocInfo varAlloc = allocation; + VarInfo::AllocInfo& varAlloc = varInfo.alloctype[arg->varId()]; varAlloc.type = allocFunc->groupId; varAlloc.status = VarInfo::ALLOC; varAlloc.allocTok = arg; - changeAllocStatus(varInfo, varAlloc, tokName, arg); } } else From d1fcc3cd403c2c34eb050fca7457ec17f381bc5f Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Tue, 14 Nov 2023 22:37:18 +0100 Subject: [PATCH 4/6] Adjust suppressions --- test/cfg/gnu.c | 7 +++---- test/cfg/sqlite3.c | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/test/cfg/gnu.c b/test/cfg/gnu.c index 8b2f84ac6f8..894f65ba0fc 100644 --- a/test/cfg/gnu.c +++ b/test/cfg/gnu.c @@ -354,15 +354,14 @@ void memleak_asprintf(char **ptr, const char *fmt, const int arg) if (-1 != asprintf(ptr,fmt,arg)) { free(ptr); } - if (-1 != asprintf(ptr,fmt,arg)) { - // TODO: Related to #8980 cppcheck-suppress memleak - } + if (-1 != asprintf(ptr,fmt,arg)) {} + // cppcheck-suppress memleak } void memleak_asprintf2() { // #12186 char* p = malloc(5); - // cppcheck-suppress memleak (void)asprintf(&p, "%s", "test"); + // cppcheck-suppress memleak } void memleak_xmalloc() diff --git a/test/cfg/sqlite3.c b/test/cfg/sqlite3.c index b294d82ab7f..b493011fc7c 100644 --- a/test/cfg/sqlite3.c +++ b/test/cfg/sqlite3.c @@ -43,7 +43,7 @@ void resourceLeak_sqlite3_open() sqlite3 * db; sqlite3_open("/db", &db); - // TODO: cppcheck-suppress resourceLeak + // cppcheck-suppress resourceLeak } void ignoredReturnValue(const char * buf) From 44d5541883aeb8011eb23d4a21ceac2a606ab0f7 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 15 Nov 2023 09:32:52 +0100 Subject: [PATCH 5/6] Use leakIfAllocated() --- lib/checkleakautovar.cpp | 1 + test/cfg/gnu.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 991fb1b1891..63a07352fb5 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -969,6 +969,7 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin const Library::AllocFunc* deallocFunc = mSettings->library.getDeallocFuncInfo(tokName); VarInfo::AllocInfo dealloc(deallocFunc ? deallocFunc->groupId : 0, VarInfo::DEALLOC, tokName); if (const Library::AllocFunc* allocFunc = mSettings->library.getAllocFuncInfo(tokName)) { + leakIfAllocated(arg, varInfo); if (allocFunc->arg == argNr) { VarInfo::AllocInfo& varAlloc = varInfo.alloctype[arg->varId()]; varAlloc.type = allocFunc->groupId; diff --git a/test/cfg/gnu.c b/test/cfg/gnu.c index 894f65ba0fc..7b7b2cfec88 100644 --- a/test/cfg/gnu.c +++ b/test/cfg/gnu.c @@ -364,6 +364,13 @@ void memleak_asprintf2() { // #12186 // cppcheck-suppress memleak } +void memleak_asprintf3() { + char* p = malloc(5); + // cppcheck-suppress memleak + asprintf(&p, "%s", "test"); + free(p); +} + void memleak_xmalloc() { char *p = (char*)xmalloc(10); From f636f7f1422aff5dbf0cf1b60c41b72eab721e17 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 15 Nov 2023 09:54:26 +0100 Subject: [PATCH 6/6] Fix --- lib/checkleakautovar.cpp | 2 +- test/cfg/gnu.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 63a07352fb5..84bb8046cbd 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -969,8 +969,8 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin const Library::AllocFunc* deallocFunc = mSettings->library.getDeallocFuncInfo(tokName); VarInfo::AllocInfo dealloc(deallocFunc ? deallocFunc->groupId : 0, VarInfo::DEALLOC, tokName); if (const Library::AllocFunc* allocFunc = mSettings->library.getAllocFuncInfo(tokName)) { - leakIfAllocated(arg, varInfo); if (allocFunc->arg == argNr) { + leakIfAllocated(arg, varInfo); VarInfo::AllocInfo& varAlloc = varInfo.alloctype[arg->varId()]; varAlloc.type = allocFunc->groupId; varAlloc.status = VarInfo::ALLOC; diff --git a/test/cfg/gnu.c b/test/cfg/gnu.c index 7b7b2cfec88..d2ded37e540 100644 --- a/test/cfg/gnu.c +++ b/test/cfg/gnu.c @@ -360,6 +360,7 @@ void memleak_asprintf(char **ptr, const char *fmt, const int arg) void memleak_asprintf2() { // #12186 char* p = malloc(5); + // cppcheck-suppress memleak (void)asprintf(&p, "%s", "test"); // cppcheck-suppress memleak }