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);