@@ -967,7 +967,7 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin
967967 while (Token::Match (arg, " %name% .|:: %name%" ))
968968 arg = arg->tokAt (2 );
969969
970- if (Token::Match (arg, " %var% [-,)] !!." ) || Token::Match (arg, " & %var%" )) {
970+ if (Token::Match (arg, " %var% [-,)] !!." ) || Token::Match (arg, " & %var% !!. " )) {
971971 // goto variable
972972 if (arg->str () == " &" )
973973 arg = arg->next ();
@@ -979,6 +979,9 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin
979979 const Library::AllocFunc* deallocFunc = mSettings ->library .getDeallocFuncInfo (tokName);
980980 VarInfo::AllocInfo dealloc (deallocFunc ? deallocFunc->groupId : 0 , VarInfo::DEALLOC, tokName);
981981 if (const Library::AllocFunc* allocFunc = mSettings ->library .getAllocFuncInfo (tokName)) {
982+ if (mSettings ->library .getDeallocFuncInfo (tokName)) {
983+ changeAllocStatus (varInfo, dealloc.type == 0 ? allocation : dealloc, tokName, arg);
984+ }
982985 if (allocFunc->arg == argNr && !(arg->variable () && arg->variable ()->isArgument () && arg->valueType () && arg->valueType ()->pointer > 1 )) {
983986 leakIfAllocated (arg, varInfo);
984987 VarInfo::AllocInfo& varAlloc = varInfo.alloctype [arg->varId ()];
@@ -1063,6 +1066,21 @@ void CheckLeakAutoVar::leakIfAllocated(const Token *vartok,
10631066 }
10641067}
10651068
1069+ static const Token* getOutparamAllocation (const Token* tok, const Settings* settings)
1070+ {
1071+ if (!tok)
1072+ return nullptr ;
1073+ int argn{};
1074+ const Token* ftok = getTokenArgumentFunction (tok, argn);
1075+ if (!ftok)
1076+ return nullptr ;
1077+ if (const Library::AllocFunc* allocFunc = settings->library .getAllocFuncInfo (ftok)) {
1078+ if (allocFunc->arg == argn + 1 )
1079+ return ftok;
1080+ }
1081+ return nullptr ;
1082+ }
1083+
10661084void CheckLeakAutoVar::ret (const Token *tok, VarInfo &varInfo, const bool isEndOfScope)
10671085{
10681086 const std::map<int , VarInfo::AllocInfo> &alloctype = varInfo.alloctype ;
@@ -1117,19 +1135,32 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO
11171135 }
11181136
11191137 // don't warn when returning after checking return value of outparam allocation
1120- if (it->second .allocTok && (tok->scope ()->type == Scope::ScopeType::eIf || tok->scope ()->type == Scope::ScopeType::eElse)) {
1138+ const Token* outparamFunc{};
1139+ if ((tok->scope ()->type == Scope::ScopeType::eIf || tok->scope ()->type == Scope::ScopeType::eElse) &&
1140+ (outparamFunc = getOutparamAllocation (it->second .allocTok , mSettings ))) {
11211141 const Scope* scope = tok->scope ();
11221142 if (scope->type == Scope::ScopeType::eElse) {
11231143 scope = scope->bodyStart ->tokAt (-2 )->scope ();
11241144 }
11251145 const Token* const ifEnd = scope->bodyStart ->previous ();
11261146 const Token* const ifStart = ifEnd->link ();
11271147 const Token* const alloc = it->second .allocTok ;
1128- if (precedes (ifStart, alloc) && succeeds (ifEnd, alloc)) {
1129- int argn{};
1130- if (const Token* ftok = getTokenArgumentFunction (alloc, argn))
1131- if (Token::Match (ftok->next ()->astParent (), " %comp%" ))
1148+ if (precedes (ifStart, alloc) && succeeds (ifEnd, alloc)) { // allocation and check in if
1149+ if (Token::Match (outparamFunc->next ()->astParent (), " %comp%" ))
1150+ continue ;
1151+ } else { // allocation result assigned to variable
1152+ const Token* const retAssign = outparamFunc->next ()->astParent ();
1153+ if (Token::simpleMatch (retAssign, " =" ) && retAssign->astOperand1 ()->varId ()) {
1154+ bool isRetComp = false ;
1155+ for (const Token* tok2 = ifStart; tok2 != ifEnd; tok2 = tok2->next ()) {
1156+ if (tok2->varId () == retAssign->astOperand1 ()->varId ()) {
1157+ isRetComp = true ;
1158+ break ;
1159+ }
1160+ }
1161+ if (isRetComp)
11321162 continue ;
1163+ }
11331164 }
11341165 }
11351166
0 commit comments