@@ -2829,6 +2829,83 @@ static const Variable *getLHSVariable(const Token *tok)
28292829 return getLHSVariableRecursive (tok->astOperand1 ());
28302830}
28312831
2832+ static bool isLifetimeOwned (const ValueType *vt, const ValueType *vtParent)
2833+ {
2834+ if (!vtParent)
2835+ return false ;
2836+ if (!vt) {
2837+ if (vtParent->type == ValueType::CONTAINER)
2838+ return true ;
2839+ return false ;
2840+ }
2841+ if (vt->type != ValueType::UNKNOWN_TYPE && vtParent->type != ValueType::UNKNOWN_TYPE) {
2842+ if (vt->pointer != vtParent->pointer )
2843+ return true ;
2844+ if (vt->type != vtParent->type ) {
2845+ if (vtParent->type == ValueType::RECORD)
2846+ return true ;
2847+ if (vtParent->type == ValueType::CONTAINER)
2848+ return true ;
2849+ }
2850+ }
2851+
2852+ return false ;
2853+ }
2854+
2855+ static bool isLifetimeBorrowed (const ValueType *vt, const ValueType *vtParent)
2856+ {
2857+ if (!vtParent)
2858+ return false ;
2859+ if (!vt)
2860+ return false ;
2861+ if (vt->type != ValueType::UNKNOWN_TYPE && vtParent->type != ValueType::UNKNOWN_TYPE) {
2862+ if (vtParent->pointer > vt->pointer )
2863+ return true ;
2864+ if (vtParent->pointer < vt->pointer && vtParent->isIntegral ())
2865+ return true ;
2866+ }
2867+
2868+ return false ;
2869+ }
2870+
2871+ bool isLifetimeBorrowed (const Token *tok, const Settings *settings)
2872+ {
2873+ if (!tok)
2874+ return true ;
2875+ if (Token::simpleMatch (tok, " ," ))
2876+ return true ;
2877+ if (!tok->astParent ())
2878+ return true ;
2879+ if (!Token::Match (tok->astParent ()->previous (), " %name% (" ) && !Token::simpleMatch (tok->astParent (), " ," )) {
2880+ if (!Token::simpleMatch (tok, " {" )) {
2881+ const ValueType *vt = tok->valueType ();
2882+ const ValueType *vtParent = tok->astParent ()->valueType ();
2883+ if (isLifetimeBorrowed (vt, vtParent))
2884+ return true ;
2885+ if (isLifetimeOwned (vt, vtParent))
2886+ return false ;
2887+ }
2888+ const Type *t = Token::typeOf (tok);
2889+ const Type *parentT = Token::typeOf (tok->astParent ());
2890+ if (t && parentT && t->classDef && parentT->classDef && t->classDef != parentT->classDef ) {
2891+ return false ;
2892+ }
2893+ } else if (Token::Match (tok->astParent ()->tokAt (-3 ), " %var% . push_back|push_front|insert|push (" ) &&
2894+ astIsContainer (tok->astParent ()->tokAt (-3 ))) {
2895+ const ValueType *vt = tok->valueType ();
2896+ const ValueType *vtCont = tok->astParent ()->tokAt (-3 )->valueType ();
2897+ if (!vtCont->containerTypeToken )
2898+ return true ;
2899+ ValueType vtParent = ValueType::parseDecl (vtCont->containerTypeToken , settings);
2900+ if (isLifetimeBorrowed (vt, &vtParent))
2901+ return true ;
2902+ if (isLifetimeOwned (vt, &vtParent))
2903+ return false ;
2904+ }
2905+
2906+ return true ;
2907+ }
2908+
28322909static void valueFlowLifetimeFunction (Token *tok, TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings);
28332910
28342911static void valueFlowLifetimeConstructor (Token *tok,
@@ -2855,8 +2932,7 @@ static void valueFlowForwardLifetime(Token * tok, TokenList *tokenlist, ErrorLog
28552932 if (!parent->astOperand2 () || parent->astOperand2 ()->values ().empty ())
28562933 return ;
28572934
2858- if (astIsPointer (parent->astOperand2 ()) && !var->isPointer () &&
2859- !(var->valueType () && var->valueType ()->isIntegral ()))
2935+ if (!isLifetimeBorrowed (parent->astOperand2 (), settings))
28602936 return ;
28612937
28622938 std::list<ValueFlow::Value> values = parent->astOperand2 ()->values ();
@@ -3075,9 +3151,6 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList *tokenlist, ErrorLog
30753151 }
30763152 } else if (Token::Match (tok->tokAt (-2 ), " %var% . push_back|push_front|insert|push|assign" ) &&
30773153 astIsContainer (tok->tokAt (-2 ))) {
3078- const Token *containerTypeTok = tok->tokAt (-2 )->valueType ()->containerTypeToken ;
3079- const Token *endTypeTok = endTemplateArgument (containerTypeTok);
3080- const bool isPointer = endTypeTok && Token::simpleMatch (endTypeTok->previous (), " *" );
30813154 Token *vartok = tok->tokAt (-2 );
30823155 std::vector<const Token *> args = getArguments (tok);
30833156 std::size_t n = args.size ();
@@ -3086,7 +3159,7 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList *tokenlist, ErrorLog
30863159 (astIsPointer (args[n - 2 ]) && astIsPointer (args[n - 1 ]))))) {
30873160 LifetimeStore{args.back (), " Added to container '" + vartok->str () + " '." , ValueFlow::Value::Object} .byDerefCopy (
30883161 vartok, tokenlist, errorLogger, settings);
3089- } else if (!args.empty () && astIsPointer (args.back ()) == isPointer ) {
3162+ } else if (!args.empty () && isLifetimeBorrowed (args.back (), settings) ) {
30903163 LifetimeStore{args.back (), " Added to container '" + vartok->str () + " '." , ValueFlow::Value::Object} .byVal (
30913164 vartok, tokenlist, errorLogger, settings);
30923165 }
0 commit comments