From cd21918520a9134586ddaa9be06ba6a752640ecb Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 19 Nov 2023 19:51:32 +0100 Subject: [PATCH] Fix FP memleak with outparam allocation (f'up to #12186) (#5677) I wonder if it is worth trying to get this right. We also have FPs when the return value is assigned to a variable, and that seems much harder to fix. --- lib/checkleakautovar.cpp | 17 +++++++++++++++++ test/cfg/gnu.c | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 3894de25521..2b3b65c8c94 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -1108,6 +1108,23 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO } } + // don't warn when returning after checking return value of outparam allocation + const Scope* scope = tok->scope(); + if (scope->type == Scope::ScopeType::eIf || scope->type== Scope::ScopeType::eElse) { + if (scope->type == Scope::ScopeType::eElse) { + scope = scope->bodyStart->tokAt(-2)->scope(); + } + const Token* const ifEnd = scope->bodyStart->previous(); + const Token* const ifStart = ifEnd->link(); + const Token* const alloc = it->second.allocTok; + if (precedes(ifStart, alloc) && succeeds(ifEnd, alloc)) { + int argn{}; + if (const Token* ftok = getTokenArgumentFunction(alloc, argn)) + if (Token::Match(ftok->next()->astParent(), "%comp%")) + continue; + } + } + // return deallocated pointer if (used != PtrUsage::NONE && it->second.status == VarInfo::DEALLOC) deallocReturnError(tok, it->second.allocTok, var->name()); diff --git a/test/cfg/gnu.c b/test/cfg/gnu.c index d7fbe6d6667..35b65e816c7 100644 --- a/test/cfg/gnu.c +++ b/test/cfg/gnu.c @@ -380,6 +380,24 @@ void memleak_asprintf5(char* p) { // cppcheck-suppress memleak } +void memleak_asprintf6(const char* fmt, const int arg) { + char* ptr; + if (-1 == asprintf(&ptr, fmt, arg)) + return; + printf("%s", ptr); + free(ptr); +} + +void memleak_asprintf7(const char* fmt, const int arg) { + char* ptr; + if (asprintf(&ptr, fmt, arg) != -1) { + printf("%s", ptr); + free(ptr); + } + else + return; +} + void memleak_xmalloc() { char *p = (char*)xmalloc(10);