Skip to content

Commit cd21918

Browse files
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.
1 parent 4addad1 commit cd21918

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

lib/checkleakautovar.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,23 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO
11081108
}
11091109
}
11101110

1111+
// don't warn when returning after checking return value of outparam allocation
1112+
const Scope* scope = tok->scope();
1113+
if (scope->type == Scope::ScopeType::eIf || scope->type== Scope::ScopeType::eElse) {
1114+
if (scope->type == Scope::ScopeType::eElse) {
1115+
scope = scope->bodyStart->tokAt(-2)->scope();
1116+
}
1117+
const Token* const ifEnd = scope->bodyStart->previous();
1118+
const Token* const ifStart = ifEnd->link();
1119+
const Token* const alloc = it->second.allocTok;
1120+
if (precedes(ifStart, alloc) && succeeds(ifEnd, alloc)) {
1121+
int argn{};
1122+
if (const Token* ftok = getTokenArgumentFunction(alloc, argn))
1123+
if (Token::Match(ftok->next()->astParent(), "%comp%"))
1124+
continue;
1125+
}
1126+
}
1127+
11111128
// return deallocated pointer
11121129
if (used != PtrUsage::NONE && it->second.status == VarInfo::DEALLOC)
11131130
deallocReturnError(tok, it->second.allocTok, var->name());

test/cfg/gnu.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,24 @@ void memleak_asprintf5(char* p) {
380380
// cppcheck-suppress memleak
381381
}
382382

383+
void memleak_asprintf6(const char* fmt, const int arg) {
384+
char* ptr;
385+
if (-1 == asprintf(&ptr, fmt, arg))
386+
return;
387+
printf("%s", ptr);
388+
free(ptr);
389+
}
390+
391+
void memleak_asprintf7(const char* fmt, const int arg) {
392+
char* ptr;
393+
if (asprintf(&ptr, fmt, arg) != -1) {
394+
printf("%s", ptr);
395+
free(ptr);
396+
}
397+
else
398+
return;
399+
}
400+
383401
void memleak_xmalloc()
384402
{
385403
char *p = (char*)xmalloc(10);

0 commit comments

Comments
 (0)