From fa86a40cd55ecda3186e05b1668791a63b7abf07 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 8 Jan 2024 14:41:53 +0100 Subject: [PATCH 01/16] Fix #12327 FP memleak when storing pointer in object --- lib/checkleakautovar.cpp | 4 ++-- test/testleakautovar.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index f58e05d66c1..72198cbe4ee 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -329,7 +329,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, // check each token { - const bool isInit = Token::Match(tok, "%var% {|(") && tok->variable() && tok == tok->variable()->nameToken(); + const bool isInit = Token::Match(tok, "%var% {|(") && tok->variable() && tok == tok->variable()->nameToken() && tok->variable()->isPointer(); const Token * nextTok = isInit ? nullptr : checkTokenInsideExpression(tok, varInfo); if (nextTok) { tok = nextTok; @@ -1184,7 +1184,7 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO const auto use = possibleUsage.find(varid); if (use == possibleUsage.end()) { leakError(tok, var->name(), it->second.type); - } else { + } else if (!use->second.first->variable()) { // TODO: handle constructors configurationInfo(tok, use->second); } } diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index c6815db4bab..53b100bc04d 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -597,6 +597,33 @@ class TestLeakAutoVar : public TestFixture { " fd->exec();\n" "}\n", true); ASSERT_EQUALS("", errout.str()); + + check("struct C {\n" // #12327 + " char* m_p;\n" + " C(char* p) : m_p(p) {}\n" + "};\n" + "std::list gli;\n" + "void f() {\n" + " std::list li;\n" + " char* p = new char[1];\n" + " C c(p);\n" + " li.push_back(c);\n" + " C c2(li.front());\n" + " delete[] c2.m_p;\n" + "}\n" + "void g() {\n" + " char* p = new char[1];\n" + " C c(p);\n" + " gli.push_back(c);\n" + "}\n" + "void h() {\n" + " std::list li;\n" + " char* p = new char[1];\n" + " C c(p);\n" + " li.push_back(c);\n" + " delete[] li.front().m_p;\n" + "}\n", true); + ASSERT_EQUALS("", errout.str()); } void isAutoDealloc() { From 87b2dd414f31f987b456671af3c9ec6a216c218a Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 8 Jan 2024 16:14:38 +0100 Subject: [PATCH 02/16] Fix checkLibraryUseIgnore warning --- lib/checkleakautovar.cpp | 4 +++- test/testleakautovar.cpp | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 72198cbe4ee..7869ebb52fd 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -181,7 +181,9 @@ void CheckLeakAutoVar::configurationInfo(const Token* tok, const std::paircheckLibrary && functionUsage.second == VarInfo::USED && (!functionUsage.first || !functionUsage.first->function() || !functionUsage.first->function()->hasBody())) { - const std::string funcStr = functionUsage.first ? mSettings->library.getFunctionName(functionUsage.first) : "f"; + std::string funcStr = functionUsage.first ? mSettings->library.getFunctionName(functionUsage.first) : "f"; + if (funcStr.empty()) + funcStr = "unknown::" + functionUsage.first->str(); reportError(tok, Severity::information, "checkLibraryUseIgnore", diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 53b100bc04d..9d0ce0e87c6 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -3003,6 +3003,12 @@ class TestLeakAutoVar : public TestFixture { " bar(p);\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("void f(int n) {\n" + " char* p = new char[n];\n" + " v.push_back(p);\n" + "}\n", /*cpp*/ true); + ASSERT_EQUALS("[test.cpp:4]: (information) --check-library: Function unknown::push_back() should have / configuration\n", errout.str()); } }; From 4fc0a1f70af21d89fbcc6e118dbd38e732efc373 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 8 Jan 2024 18:12:46 +0100 Subject: [PATCH 03/16] Fix #12332 FN memleak for allocation functions with std:: prefix (regression) --- lib/library.cpp | 8 ++++++-- test/cfg/std.cpp | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/library.cpp b/lib/library.cpp index f1058c7883a..b172bdc6914 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -1060,14 +1060,18 @@ bool Library::isuninitargbad(const Token *ftok, int argnr, int indirect, bool *h /** get allocation info for function */ const Library::AllocFunc* Library::getAllocFuncInfo(const Token *tok) const { - const std::string funcname = getFunctionName(tok); + std::string funcname = getFunctionName(tok); + if (startsWith(funcname, "std::")) + funcname.erase(0, 5); return isNotLibraryFunction(tok) && functions.find(funcname) != functions.end() ? nullptr : getAllocDealloc(mAlloc, funcname); } /** get deallocation info for function */ const Library::AllocFunc* Library::getDeallocFuncInfo(const Token *tok) const { - const std::string funcname = getFunctionName(tok); + std::string funcname = getFunctionName(tok); + if (startsWith(funcname, "std::")) + funcname.erase(0, 5); return isNotLibraryFunction(tok) && functions.find(funcname) != functions.end() ? nullptr : getAllocDealloc(mDealloc, funcname); } diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 28279b77a6f..fa70883d722 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -4860,3 +4860,16 @@ void std_vector_data_arithmetic() buf.resize(1); memcpy(buf.data() + 0, "", 1); } + +void memleak_std_malloc() // #12332 +{ + void* p = std::malloc(1); + //cppcheck-suppress memleak +} + +void unusedAllocatedMemory_std_free() +{ + //cppcheck-suppress unusedAllocatedMemory + void* p = std::malloc(1); + std::free(p); +} \ No newline at end of file From a40ecfc73773b635cde1dd52289b7f6d0ed2ef26 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 8 Jan 2024 19:15:43 +0100 Subject: [PATCH 04/16] Fix test --- test/cfg/std.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index fa70883d722..68b1f2fd228 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -1583,6 +1583,7 @@ void uninitvar_fdim(void) void uninitvar_fclose(void) { + // cppcheck-suppress unassignedVariable FILE *stream; // cppcheck-suppress uninitvar (void)std::fclose(stream); @@ -1815,6 +1816,7 @@ void uninitvar_fread(void) void uninitvar_free(void) { + // cppcheck-suppress unassignedVariable void *block; // cppcheck-suppress uninitvar std::free(block); @@ -4863,6 +4865,7 @@ void std_vector_data_arithmetic() void memleak_std_malloc() // #12332 { + //cppcheck-suppress [unreadVariable, constVariablePointer] void* p = std::malloc(1); //cppcheck-suppress memleak } From c1c91a3a0146e181baad035a7a6ef0aa32e20dbf Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 10 Jan 2024 16:41:30 +0100 Subject: [PATCH 05/16] std::rand --- cfg/std.cfg | 2 +- test/cfg/std.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cfg/std.cfg b/cfg/std.cfg index b32b4cae74a..b3ca7dfce73 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -3172,7 +3172,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + false diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 68b1f2fd228..455a36528cc 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -2527,6 +2527,8 @@ void uninitvar_srand(void) unsigned int seed; // cppcheck-suppress uninitvar (void)std::srand(seed); + // cppcheck-suppress ignoredReturnValue + std::rand(); } void uninitvar_ldiv(void) From f6d929a9f72d50d7f0a2469a4460bdcee4497bc7 Mon Sep 17 00:00:00 2001 From: chrchr Date: Thu, 11 Jan 2024 11:52:54 +0100 Subject: [PATCH 06/16] std::realloc --- lib/library.cpp | 8 +++++--- test/cfg/std.cpp | 7 +++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/library.cpp b/lib/library.cpp index b172bdc6914..d28d6e02070 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -1061,7 +1061,7 @@ bool Library::isuninitargbad(const Token *ftok, int argnr, int indirect, bool *h const Library::AllocFunc* Library::getAllocFuncInfo(const Token *tok) const { std::string funcname = getFunctionName(tok); - if (startsWith(funcname, "std::")) + if (tok->isCpp() && startsWith(funcname, "std::")) funcname.erase(0, 5); return isNotLibraryFunction(tok) && functions.find(funcname) != functions.end() ? nullptr : getAllocDealloc(mAlloc, funcname); } @@ -1070,7 +1070,7 @@ const Library::AllocFunc* Library::getAllocFuncInfo(const Token *tok) const const Library::AllocFunc* Library::getDeallocFuncInfo(const Token *tok) const { std::string funcname = getFunctionName(tok); - if (startsWith(funcname, "std::")) + if (tok->isCpp() && startsWith(funcname, "std::")) funcname.erase(0, 5); return isNotLibraryFunction(tok) && functions.find(funcname) != functions.end() ? nullptr : getAllocDealloc(mDealloc, funcname); } @@ -1078,7 +1078,9 @@ const Library::AllocFunc* Library::getDeallocFuncInfo(const Token *tok) const /** get reallocation info for function */ const Library::AllocFunc* Library::getReallocFuncInfo(const Token *tok) const { - const std::string funcname = getFunctionName(tok); + std::string funcname = getFunctionName(tok); + if (tok->isCpp() && startsWith(funcname, "std::")) + funcname.erase(0, 5); return isNotLibraryFunction(tok) && functions.find(funcname) != functions.end() ? nullptr : getAllocDealloc(mRealloc, funcname); } diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 455a36528cc..40a4314419b 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -4872,6 +4872,13 @@ void memleak_std_malloc() // #12332 //cppcheck-suppress memleak } +void memleak_std_realloc(void* block, size_t newsize) +{ + //cppcheck-suppress [unreadVariable, constVariablePointer] + void* p = std::realloc(block, newsize); + //cppcheck-suppress memleak +} + void unusedAllocatedMemory_std_free() { //cppcheck-suppress unusedAllocatedMemory From 17bcbec60fe7d8c3589db2b2ab7a871a464cbd6c Mon Sep 17 00:00:00 2001 From: chrchr Date: Thu, 11 Jan 2024 12:00:54 +0100 Subject: [PATCH 07/16] Fix test --- test/cfg/std.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 40a4314419b..810229d0f89 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -1829,7 +1829,7 @@ void uninitvar_freopen(void) FILE *stream; // cppcheck-suppress uninitvar FILE * p = std::freopen(filename,mode,stream); - free(p); + std::fclose(p); } void uninitvar_frexp(void) From eb617fa86f05391758a08007f697cafdb6aa3e0f Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 15 Jan 2024 11:36:43 +0100 Subject: [PATCH 08/16] Add std aliases to library --- cfg/std.cfg | 24 ++++++++++++------------ lib/library.cpp | 38 ++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/cfg/std.cfg b/cfg/std.cfg index b3ca7dfce73..2c55368d479 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -8588,22 +8588,22 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - malloc - calloc - aligned_alloc - realloc - reallocarray - free + malloc,std::malloc + calloc,std::calloc + aligned_alloc,std::aligned_alloc + realloc,std::realloc + reallocarray,std::reallocarray + free,std::free - strdup - free + strdup,std::strdup + free,std::free - fopen - tmpfile - freopen - fclose + fopen,std::fopen + tmpfile,std::tmpfile + freopen,std::freopen + fclose,std::fclose diff --git a/lib/library.cpp b/lib/library.cpp index d28d6e02070..777cc408246 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -216,11 +216,13 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) int allocationId = 0; for (const tinyxml2::XMLElement *memorynode = node->FirstChildElement(); memorynode; memorynode = memorynode->NextSiblingElement()) { if (strcmp(memorynode->Name(),"dealloc")==0) { - const std::map::const_iterator it = mDealloc.find(memorynode->GetText()); - if (it != mDealloc.end()) { - allocationId = it->second.groupId; - break; + const auto names = getnames(memorynode->GetText()); + for (const auto& n : names) { + const std::map::const_iterator it = mDealloc.find(n); + if (it != mDealloc.end()) + allocationId = it->second.groupId; } + break; } } if (allocationId == 0) { @@ -234,7 +236,8 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) // add alloc/dealloc/use functions.. for (const tinyxml2::XMLElement *memorynode = node->FirstChildElement(); memorynode; memorynode = memorynode->NextSiblingElement()) { const std::string memorynodename = memorynode->Name(); - if (memorynodename == "alloc" || memorynodename == "realloc") { + const auto names = getnames(memorynode->GetText()); + if (memorynodename == "alloc" || memorynodename == "realloc") { AllocFunc temp = {0}; temp.groupId = allocationId; @@ -268,17 +271,18 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) if (memorynodename == "realloc") temp.reallocArg = memorynode->IntAttribute("realloc-arg", 1); - if (memorynodename != "realloc") - mAlloc[memorynode->GetText()] = temp; - else - mRealloc[memorynode->GetText()] = temp; + auto& map = (memorynodename == "realloc") ? mRealloc : mAlloc; + for (const auto& n : names) + map[n] = temp; } else if (memorynodename == "dealloc") { AllocFunc temp = {0}; temp.groupId = allocationId; temp.arg = memorynode->IntAttribute("arg", 1); - mDealloc[memorynode->GetText()] = temp; + for (const auto& n : names) + mDealloc[n] = temp; } else if (memorynodename == "use") - functions[memorynode->GetText()].use = true; + for (const auto& n : names) + functions[n].use = true; else unknown_elements.insert(memorynodename); } @@ -1060,27 +1064,21 @@ bool Library::isuninitargbad(const Token *ftok, int argnr, int indirect, bool *h /** get allocation info for function */ const Library::AllocFunc* Library::getAllocFuncInfo(const Token *tok) const { - std::string funcname = getFunctionName(tok); - if (tok->isCpp() && startsWith(funcname, "std::")) - funcname.erase(0, 5); + const std::string funcname = getFunctionName(tok); return isNotLibraryFunction(tok) && functions.find(funcname) != functions.end() ? nullptr : getAllocDealloc(mAlloc, funcname); } /** get deallocation info for function */ const Library::AllocFunc* Library::getDeallocFuncInfo(const Token *tok) const { - std::string funcname = getFunctionName(tok); - if (tok->isCpp() && startsWith(funcname, "std::")) - funcname.erase(0, 5); + const std::string funcname = getFunctionName(tok); return isNotLibraryFunction(tok) && functions.find(funcname) != functions.end() ? nullptr : getAllocDealloc(mDealloc, funcname); } /** get reallocation info for function */ const Library::AllocFunc* Library::getReallocFuncInfo(const Token *tok) const { - std::string funcname = getFunctionName(tok); - if (tok->isCpp() && startsWith(funcname, "std::")) - funcname.erase(0, 5); + const std::string funcname = getFunctionName(tok); return isNotLibraryFunction(tok) && functions.find(funcname) != functions.end() ? nullptr : getAllocDealloc(mRealloc, funcname); } From 827326fcae600b4f3a22467f7f9ca302a10d0290 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 15 Jan 2024 12:04:56 +0100 Subject: [PATCH 09/16] Fix schema --- cfg/cppcheck-cfg.rng | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cfg/cppcheck-cfg.rng b/cfg/cppcheck-cfg.rng index f3a3c1f7be2..5dd446c1778 100644 --- a/cfg/cppcheck-cfg.rng +++ b/cfg/cppcheck-cfg.rng @@ -35,7 +35,7 @@ - + @@ -50,7 +50,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -87,7 +87,7 @@ - + From 362b9e60e3bebf18281a10b9aaf25f8f9d471cba Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 15 Jan 2024 12:07:50 +0100 Subject: [PATCH 10/16] Format --- lib/library.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/library.cpp b/lib/library.cpp index a90d92fe83e..bd19496fd17 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -237,7 +237,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) for (const tinyxml2::XMLElement *memorynode = node->FirstChildElement(); memorynode; memorynode = memorynode->NextSiblingElement()) { const std::string memorynodename = memorynode->Name(); const auto names = getnames(memorynode->GetText()); - if (memorynodename == "alloc" || memorynodename == "realloc") { + if (memorynodename == "alloc" || memorynodename == "realloc") { AllocFunc temp = {0}; temp.groupId = allocationId; From e0c741a04644c31bd24724ac623f03f94b5bbeb5 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 15 Jan 2024 14:10:17 +0100 Subject: [PATCH 11/16] Move reallocarray() to bsd.cfg --- cfg/bsd.cfg | 4 ++++ cfg/std.cfg | 1 - test/cfg/bsd.c | 15 +++++++++++++++ test/cfg/std.c | 5 ----- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/cfg/bsd.cfg b/cfg/bsd.cfg index 751bb03c00e..bfeefbb20d8 100644 --- a/cfg/bsd.cfg +++ b/cfg/bsd.cfg @@ -518,6 +518,10 @@ + + reallocarray + free + diff --git a/cfg/std.cfg b/cfg/std.cfg index 7f6b80e96ce..b1439f8e833 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -8603,7 +8603,6 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init calloc,std::calloc aligned_alloc,std::aligned_alloc realloc,std::realloc - reallocarray,std::reallocarray free,std::free diff --git a/test/cfg/bsd.c b/test/cfg/bsd.c index 227e327c982..030e636d363 100644 --- a/test/cfg/bsd.c +++ b/test/cfg/bsd.c @@ -144,3 +144,18 @@ void uninitvar(void) // cppcheck-suppress uninitvar (void) arc4random_uniform(uint32Uninit); } + +void arrayIndexOutOfBounds(void) +{ + char * pAlloc = calloc(2, 3); + pAlloc[5] = 'a'; + // cppcheck-suppress arrayIndexOutOfBounds + pAlloc[6] = 1; + // cppcheck-suppress memleakOnRealloc + pAlloc = reallocarray(pAlloc, 3, 3); + pAlloc[8] = 'a'; + // cppcheck-suppress arrayIndexOutOfBounds + pAlloc[9] = 1; + free(pAlloc); +} + diff --git a/test/cfg/std.c b/test/cfg/std.c index ec5725d09be..9f2a0d213cf 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -348,11 +348,6 @@ void arrayIndexOutOfBounds() pAlloc3[5] = 'a'; // cppcheck-suppress arrayIndexOutOfBounds pAlloc3[6] = 1; - // cppcheck-suppress memleakOnRealloc - pAlloc3 = reallocarray(pAlloc3, 3,3); - pAlloc3[8] = 'a'; - // cppcheck-suppress arrayIndexOutOfBounds - pAlloc3[9] = 1; free(pAlloc3); } From 57ec3d3ecc340d64e8acfac048384ac2347d093f Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 15 Jan 2024 14:21:48 +0100 Subject: [PATCH 12/16] Fix --- test/cfg/bsd.c | 11 +++++++++++ test/testmemleak.cpp | 16 ---------------- test/testvalueflow.cpp | 1 + 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/test/cfg/bsd.c b/test/cfg/bsd.c index 030e636d363..52583266ac1 100644 --- a/test/cfg/bsd.c +++ b/test/cfg/bsd.c @@ -159,3 +159,14 @@ void arrayIndexOutOfBounds(void) free(pAlloc); } +void reallocarray_memleak(void) { + char *a = (char *)malloc(10);\n" + // cppcheck-suppress memleakOnRealloc + a = reallocarray(a, 100, 2);\n" +} + +void reallocarray_notused(void) +{ + // cppcheck-suppress leakReturnValNotUsed + reallocarray(NULL, 10, 10); +} diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 7358cd97fb6..4987f2bdc92 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -166,7 +166,6 @@ class TestMemleakInFunction : public TestFixture { TEST_CASE(realloc22); TEST_CASE(realloc23); TEST_CASE(realloc24); // #9228 - TEST_CASE(reallocarray1); } void realloc1() { @@ -435,15 +434,6 @@ class TestMemleakInFunction : public TestFixture { "}"); ASSERT_EQUALS("", errout.str()); } - - void reallocarray1() { - check("void foo()\n" - "{\n" - " char *a = (char *)malloc(10);\n" - " a = reallocarray(a, 100, 2);\n" - "}"); - ASSERT_EQUALS("[test.cpp:4]: (error) Common reallocarray mistake: \'a\' nulled but not freed upon failure\n", errout.str()); - } }; REGISTER_TEST(TestMemleakInFunction) @@ -2521,12 +2511,6 @@ class TestMemleakNoVar : public TestFixture { "}"); ASSERT_EQUALS("[test.cpp:3]: (error) Return value of allocation function 'strdup' is not stored.\n", errout.str()); - check("void x()\n" - "{\n" - " reallocarray(NULL, 10, 10);\n" - "}"); - ASSERT_EQUALS("[test.cpp:3]: (error) Return value of allocation function 'reallocarray' is not stored.\n", errout.str()); - check("void x()\n" "{\n" " (char*) malloc(10);\n" diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index c7eda198184..73e34ca763b 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -6828,6 +6828,7 @@ class TestValueFlow : public TestFixture { LOAD_LIB_2(settings.library, "std.cfg"); LOAD_LIB_2(settings.library, "posix.cfg"); + LOAD_LIB_2(settings.library, "bsd.cfg"); code = "void* f() {\n" " void* x = malloc(10);\n" From 5a4baabdccef8e8f500f1759a89cca5bc060eed4 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 15 Jan 2024 14:47:43 +0100 Subject: [PATCH 13/16] Fix --- test/cfg/bsd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cfg/bsd.c b/test/cfg/bsd.c index 52583266ac1..e9f64cf4b2e 100644 --- a/test/cfg/bsd.c +++ b/test/cfg/bsd.c @@ -160,9 +160,9 @@ void arrayIndexOutOfBounds(void) } void reallocarray_memleak(void) { - char *a = (char *)malloc(10);\n" + char *a = (char *)malloc(10); // cppcheck-suppress memleakOnRealloc - a = reallocarray(a, 100, 2);\n" + a = reallocarray(a, 100, 2); } void reallocarray_notused(void) From 8de767775871d3495cc20fc736a30b6277906faf Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 15 Jan 2024 15:56:25 +0100 Subject: [PATCH 14/16] Fix --- test/cfg/bsd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/cfg/bsd.c b/test/cfg/bsd.c index e9f64cf4b2e..734a97fe4aa 100644 --- a/test/cfg/bsd.c +++ b/test/cfg/bsd.c @@ -161,12 +161,13 @@ void arrayIndexOutOfBounds(void) void reallocarray_memleak(void) { char *a = (char *)malloc(10); - // cppcheck-suppress memleakOnRealloc + // cppcheck-suppress [memleakOnRealloc, unreadVariable] a = reallocarray(a, 100, 2); + // cppcheck-suppress memleak } void reallocarray_notused(void) { - // cppcheck-suppress leakReturnValNotUsed + // cppcheck-suppress [leakReturnValNotUsed, ignoredReturnValue] reallocarray(NULL, 10, 10); } From e90a8018b7cacf51487315ad6dedc9dc88d0c574 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 15 Jan 2024 19:19:18 +0100 Subject: [PATCH 15/16] Move --- cfg/bsd.cfg | 17 +++++++++++++++++ cfg/std.cfg | 17 ----------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/cfg/bsd.cfg b/cfg/bsd.cfg index bfeefbb20d8..158d7a8a885 100644 --- a/cfg/bsd.cfg +++ b/cfg/bsd.cfg @@ -518,6 +518,23 @@ + + + + + false + + + + + + 0: + + + + 0: + + reallocarray free diff --git a/cfg/std.cfg b/cfg/std.cfg index b1439f8e833..6185c37ebfc 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -4572,23 +4572,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun 0: - - - - - false - - - - - - 0: - - - - 0: - - From 6dc15088e3def31568c7df6c611979872f18e5f6 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Wed, 17 Jan 2024 22:26:48 +0100 Subject: [PATCH 16/16] Restore, add alias --- cfg/std.cfg | 2 +- lib/library.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cfg/std.cfg b/cfg/std.cfg index 6185c37ebfc..7fb77addfd3 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -965,7 +965,7 @@ - + false diff --git a/lib/library.cpp b/lib/library.cpp index bd19496fd17..1e0ae2f8653 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -219,10 +219,13 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) const auto names = getnames(memorynode->GetText()); for (const auto& n : names) { const std::map::const_iterator it = mDealloc.find(n); - if (it != mDealloc.end()) + if (it != mDealloc.end()) { allocationId = it->second.groupId; + break; + } } - break; + if (allocationId != 0) + break; } } if (allocationId == 0) {