MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / checkReallocUsage

Method checkReallocUsage

lib/checkmemoryleak.cpp:418–488  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

416//---------------------------------------------------------------------------
417
418void CheckMemoryLeakInFunctionImpl::checkReallocUsage()
419{
420 logChecker("CheckMemoryLeakInFunction::checkReallocUsage");
421
422 // only check functions
423 const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
424 for (const Scope * scope : symbolDatabase->functionScopes) {
425
426 // Search for the "var = realloc(var, 100" pattern within this function
427 for (const Token *tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) {
428 if (tok->varId() > 0 && Token::Match(tok, "%name% =")) {
429 // Get the parenthesis in "realloc("
430 const Token* parTok = tok->next()->astOperand2();
431 // Skip casts
432 while (parTok && parTok->isCast())
433 parTok = parTok->astOperand1();
434 if (!parTok)
435 continue;
436
437 const Token *const reallocTok = parTok->astOperand1();
438 if (!reallocTok)
439 continue;
440 const Library::AllocFunc* f = mSettings.library.getReallocFuncInfo(reallocTok);
441 if (!(f && f->arg == -1 && mSettings.library.isnotnoreturn(reallocTok)))
442 continue;
443
444 const AllocType allocType = getReallocationType(reallocTok, tok->varId());
445 if (!(allocType == Malloc || allocType == OtherMem))
446 continue;
447 const Token* arg = getArguments(reallocTok).at(f->reallocArg - 1);
448 while (arg && arg->isCast())
449 arg = arg->astOperand1();
450 const Token* tok2 = tok;
451 while (arg && arg->isUnaryOp("*") && tok2 && tok2->astParent() && tok2->astParent()->isUnaryOp("*")) {
452 arg = arg->astOperand1();
453 tok2 = tok2->astParent();
454 }
455
456 if (!arg || !tok2)
457 continue;
458
459 if (!(tok->varId() == arg->varId() && tok->variable() && !tok->variable()->isArgument()))
460 continue;
461
462 // Check that another copy of the pointer wasn't saved earlier in the function
463 if (Token::findmatch(scope->bodyStart, "%name% = %varid% ;", tok, tok->varId()) ||
464 Token::findmatch(scope->bodyStart, "[{};] %varid% = *| %var%", tok, tok->varId()))
465 continue;
466 if (const Token* storeTok = Token::findmatch(scope->bodyStart, "[{};] %varid% = %name% (", tok, tok->varId()))
467 if (storeTok->tokAt(3) != reallocTok && !mSettings.library.getAllocFuncInfo(storeTok->tokAt(3)))
468 continue;
469
470 // Check if the argument is known to be null, which means it is not a memory leak
471 if (arg->hasKnownIntValue() && arg->getKnownIntValue() == 0) {
472 continue;
473 }
474
475 const Token* tokEndRealloc = reallocTok->linkAt(1);

Callers 2

runChecksMethod · 0.80
check_Method · 0.80

Calls 15

notvarFunction · 0.85
nextMethod · 0.80
astOperand2Method · 0.80
isCastMethod · 0.80
astOperand1Method · 0.80
getReallocFuncInfoMethod · 0.80
isnotnoreturnMethod · 0.80
atMethod · 0.80
isUnaryOpMethod · 0.80
astParentMethod · 0.80
variableMethod · 0.80
getAllocFuncInfoMethod · 0.80

Tested by 1

check_Method · 0.64