@@ -2108,6 +2108,24 @@ static bool evalAssignment(Value& lhsValue, const std::string& assign, const Val
21082108 return !error;
21092109}
21102110
2111+ static ValueFlow::Value::MoveKind isMoveOrForward (const Token* tok)
2112+ {
2113+ if (!tok)
2114+ return ValueFlow::Value::MoveKind::NonMovedVariable;
2115+ const Token* parent = tok->astParent ();
2116+ if (!Token::simpleMatch (parent, " (" ))
2117+ return ValueFlow::Value::MoveKind::NonMovedVariable;
2118+ const Token* ftok = parent->astOperand1 ();
2119+ if (!ftok)
2120+ return ValueFlow::Value::MoveKind::NonMovedVariable;
2121+ if (Token::simpleMatch (ftok->astOperand1 (), " std :: move" ))
2122+ return ValueFlow::Value::MoveKind::MovedVariable;
2123+ if (Token::simpleMatch (ftok->astOperand1 (), " std :: forward" ))
2124+ return ValueFlow::Value::MoveKind::ForwardedVariable;
2125+ // TODO: Check for cast
2126+ return ValueFlow::Value::MoveKind::NonMovedVariable;
2127+ }
2128+
21112129template <class T >
21122130struct SingleRange {
21132131 T* x;
@@ -2416,6 +2434,19 @@ struct ValueFlowAnalyzer : Analyzer {
24162434
24172435 virtual Action isModified (const Token* tok) const {
24182436 Action read = Action::Read;
2437+ const ValueFlow::Value* value = getValue (tok);
2438+ if (value) {
2439+ // Moving a moved value wont change the moved value
2440+ if (value->isMovedValue () && isMoveOrForward (tok) != ValueFlow::Value::MoveKind::NonMovedVariable)
2441+ return read;
2442+ // Inserting elements to container wont change the lifetime
2443+ if (astIsContainer (tok) && value->isLifetimeValue () &&
2444+ contains ({Library::Container::Action::PUSH ,
2445+ Library::Container::Action::INSERT ,
2446+ Library::Container::Action::CHANGE_INTERNAL },
2447+ astContainerAction (tok)))
2448+ return read;
2449+ }
24192450 bool inconclusive = false ;
24202451 if (isVariableChangedByFunctionCall (tok, getIndirect (tok), getSettings (), &inconclusive))
24212452 return read | Action::Invalid;
@@ -2424,7 +2455,6 @@ struct ValueFlowAnalyzer : Analyzer {
24242455 if (isVariableChanged (tok, getIndirect (tok), getSettings (), isCPP ())) {
24252456 if (Token::Match (tok->astParent (), " *|[|.|++|--" ))
24262457 return read | Action::Invalid;
2427- const ValueFlow::Value* value = getValue (tok);
24282458 // Check if its assigned to the same value
24292459 if (value && !value->isImpossible () && Token::simpleMatch (tok->astParent (), " =" ) && astIsLHS (tok) &&
24302460 astIsIntegral (tok->astParent ()->astOperand2 (), false )) {
0 commit comments