From e621f721fcef407286b0f4f0657d52f42e6918a6 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 21 May 2023 14:01:14 +0200 Subject: [PATCH] Use library to get deallocation function (#5061) * Use library to get deallocation function * Add suppressions * Amend * Remove suppression * More getDeallocFuncInfo() * Fix suppressions * Fix suppression --- lib/checkclass.cpp | 2 +- lib/checkmemoryleak.cpp | 4 ++-- lib/checkother.cpp | 2 +- lib/checkunusedvar.cpp | 2 +- test/cfg/gtk.c | 1 + test/cfg/posix.c | 1 + test/cfg/python.c | 2 ++ test/cfg/std.c | 1 + test/cfg/std.cpp | 1 - test/cfg/windows.cpp | 8 +++++++- 10 files changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 3757966ec..4192286da 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1738,7 +1738,7 @@ bool CheckClass::hasAllocation(const Function *func, const Scope* scope, const T // check for deallocating memory const Token *var; - if (Token::Match(tok, "free ( %var%")) + if (Token::Match(tok, "%name% ( %var%") && mSettings->library.getDeallocFuncInfo(tok)) var = tok->tokAt(2); else if (Token::Match(tok, "delete [ ] %var%")) var = tok->tokAt(3); diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 2f006fca7..bffbd89e8 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -876,7 +876,7 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var } // Deallocating the struct.. - else if (Token::Match(tok3, "free|kfree ( %varid% )", structid)) { + else if (Token::Match(tok3, "%name% ( %varid% )", structid) && mSettings->library.getDeallocFuncInfo(tok3)) { if (indentlevel2 == 0) memoryLeak(tok3, variable->name() + "." + tok2->strAt(2), Malloc); break; @@ -910,7 +910,7 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var --indentlevel4; if (indentlevel4 == 0) break; - } else if (Token::Match(tok4, "free|kfree ( %var% . %varid% )", structmemberid)) { + } else if (Token::Match(tok4, "%name% ( %var% . %varid% )", structmemberid) && mSettings->library.getDeallocFuncInfo(tok4)) { break; } } diff --git a/lib/checkother.cpp b/lib/checkother.cpp index f2920a46f..b82df24e9 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2323,7 +2323,7 @@ void CheckOther::checkInvalidFree() // If a variable that was previously assigned a newly-allocated memory location is // added or subtracted from when used to free the memory, report an error. - else if (Token::Match(tok, "free|g_free|delete ( %any% +|-") || + else if ((Token::Match(tok, "%name% ( %any% +|-") && mSettings->library.getDeallocFuncInfo(tok)) || Token::Match(tok, "delete [ ] ( %any% +|-") || Token::Match(tok, "delete %any% +|- %any%")) { diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 5a47ba8d6..0bf9ca3d0 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -837,7 +837,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const } } // Freeing memory (not considered "using" the pointer if it was also allocated in this function) - if (Token::Match(tok, "free|g_free|kfree|vfree ( %var% )") || + if ((Token::Match(tok, "%name% ( %var% )") && mSettings->library.getDeallocFuncInfo(tok)) || (mTokenizer->isCPP() && (Token::Match(tok, "delete %var% ;") || Token::Match(tok, "delete [ ] %var% ;")))) { nonneg int varid = 0; if (tok->str() != "delete") { diff --git a/test/cfg/gtk.c b/test/cfg/gtk.c index 11b028f91..2286307a6 100644 --- a/test/cfg/gtk.c +++ b/test/cfg/gtk.c @@ -51,6 +51,7 @@ void validCode(int argInt, GHashTableIter * hash_table_iter, GHashTable * hash_t printf("%s", pGchar1); g_free(pGchar1); + // cppcheck-suppress unusedAllocatedMemory GError * pGerror = g_error_new(1, -2, "a %d", 1); g_error_free(pGerror); diff --git a/test/cfg/posix.c b/test/cfg/posix.c index 61d7c3cf0..51150b568 100644 --- a/test/cfg/posix.c +++ b/test/cfg/posix.c @@ -1287,6 +1287,7 @@ void dl(const char* libname, const char* func) void* sym = dlsym(lib, funcname); // cppcheck-suppress ignoredReturnValue dlsym(lib, "foo"); + // cppcheck-suppress unassignedVariable void* uninit; // cppcheck-suppress uninitvar dlclose(uninit); diff --git a/test/cfg/python.c b/test/cfg/python.c index 266f6d9fa..f664bc4b7 100644 --- a/test/cfg/python.c +++ b/test/cfg/python.c @@ -25,8 +25,10 @@ void validCode(PyObject * pPyObjArg) Py_CLEAR(pPyObjNULL); (void)PyErr_NewException("text", NULL, NULL); + // cppcheck-suppress unusedAllocatedMemory char * pBuf1 = PyMem_Malloc(5); PyMem_Free(pBuf1); + // cppcheck-suppress unusedAllocatedMemory int * pIntBuf1 = PyMem_New(int, 10); PyMem_Free(pIntBuf1); } diff --git a/test/cfg/std.c b/test/cfg/std.c index 958d99aa3..a2183b17d 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -648,6 +648,7 @@ void uninitvar_clearerr(void) void uninitvar_fclose(void) { + // cppcheck-suppress unassignedVariable FILE *fp; // cppcheck-suppress uninitvar fclose(fp); diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 66b86264b..fd00d8fc7 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -1795,7 +1795,6 @@ void uninitvar_fread(void) void uninitvar_free(void) { - // cppcheck-suppress unassignedVariable void *block; // cppcheck-suppress uninitvar std::free(block); diff --git a/test/cfg/windows.cpp b/test/cfg/windows.cpp index b1d8da82e..45039f9b3 100644 --- a/test/cfg/windows.cpp +++ b/test/cfg/windows.cpp @@ -258,6 +258,7 @@ void validCode() CloseHandle(event); } + // cppcheck-suppress unusedAllocatedMemory void *pMem1 = _malloca(1); _freea(pMem1); // Memory from _alloca must not be freed @@ -343,7 +344,7 @@ void validCode() SecureZeroMemory(byteBuf, sizeof(byteBuf)); RtlFillMemory(byteBuf, sizeof(byteBuf), 0xff); - // cppcheck-suppress LocalAllocCalled + // cppcheck-suppress [LocalAllocCalled, unusedAllocatedMemory] HLOCAL pLocalAlloc = LocalAlloc(1, 2); LocalFree(pLocalAlloc); @@ -357,6 +358,7 @@ void validCode() __noop(1, "test", NULL); __nop(); + // cppcheck-suppress unusedAllocatedMemory void * pAlloc1 = _aligned_malloc(100, 2); _aligned_free(pAlloc1); @@ -437,6 +439,7 @@ void mismatchAllocDealloc() // cppcheck-suppress mismatchAllocDealloc free(pChar); + // cppcheck-suppress unusedAllocatedMemory pChar = _malloca(32); // cppcheck-suppress mismatchAllocDealloc _aligned_free(pChar); @@ -751,6 +754,7 @@ void invalidFunctionArg() void uninitvar() { + // cppcheck-suppress unassignedVariable HANDLE hSemaphore; // cppcheck-suppress uninitvar CloseHandle(hSemaphore); @@ -765,12 +769,14 @@ void uninitvar() // cppcheck-suppress uninitvar lstrcat(buf, buf2); + // cppcheck-suppress unassignedVariable HANDLE hMutex1, hMutex2; // cppcheck-suppress uninitvar ReleaseMutex(hMutex1); // cppcheck-suppress uninitvar CloseHandle(hMutex2); + // cppcheck-suppress unassignedVariable HANDLE hEvent1, hEvent2, hEvent3, hEvent4; // cppcheck-suppress uninitvar PulseEvent(hEvent1);