@@ -363,6 +363,40 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
363
363
while (Token::Match (ftok, " %name% :: %name%" ))
364
364
ftok = ftok->tokAt (2 );
365
365
366
+ // bailout for variable passed to library function with out parameter
367
+ if (const Library::Function *libFunc = mSettings ->library .getFunction (ftok)) {
368
+ using ArgumentChecks = Library::ArgumentChecks;
369
+ using Direction = ArgumentChecks::Direction;
370
+ const std::vector<const Token *> args = getArguments (ftok);
371
+ const std::map<int , ArgumentChecks> &argChecks = libFunc->argumentChecks ;
372
+ bool hasOutParam = std::any_of (argChecks.cbegin (), argChecks.cend (), [](const std::pair<int , ArgumentChecks> &pair) {
373
+ return std::any_of (pair.second .direction .cbegin (), pair.second .direction .cend (), [](const Direction dir) {
374
+ return dir == Direction::DIR_OUT;
375
+ });
376
+ });
377
+ if (hasOutParam) {
378
+ for (int i = 0 ; i < args.size (); i++) {
379
+ if (!argChecks.count (i + 1 ))
380
+ continue ;
381
+ const ArgumentChecks argCheck = argChecks.at (i + 1 );
382
+ const bool isInParam = std::any_of (argCheck.direction .cbegin (), argCheck.direction .cend (), [&](const Direction dir) {
383
+ return dir == Direction::DIR_IN;
384
+ });
385
+ if (!isInParam)
386
+ continue ;
387
+ const Token *inTok = args[i];
388
+ int indirect = 0 ;
389
+ while (inTok->isUnaryOp (" &" )) {
390
+ inTok = inTok->astOperand1 ();
391
+ indirect++;
392
+ }
393
+ if (inTok->isVariable () && indirect) {
394
+ varInfo.erase (inTok->varId ());
395
+ }
396
+ }
397
+ }
398
+ }
399
+
366
400
auto isAssignment = [](const Token* varTok) -> const Token* {
367
401
if (varTok->varId ()) {
368
402
const Token* top = varTok;
0 commit comments