@@ -697,14 +697,47 @@ static const Token * getIteratorExpression(const Token * tok)
697697 return nullptr ;
698698}
699699
700+ static const Token* getAddressContainer (const Token* tok)
701+ {
702+ if (Token::simpleMatch (tok, " [" ) && tok->astOperand1 ())
703+ return tok->astOperand1 ();
704+ return tok;
705+ }
706+
707+ static bool isSameIteratorContainerExpression (const Token* tok1,
708+ const Token* tok2,
709+ const Library& library,
710+ ValueFlow::Value::LifetimeKind kind = ValueFlow::Value::LifetimeKind::Iterator)
711+ {
712+ if (isSameExpression (true , false , tok1, tok2, library, false , false ))
713+ return true ;
714+ if (kind == ValueFlow::Value::LifetimeKind::Address) {
715+ return isSameExpression (true , false , getAddressContainer (tok1), getAddressContainer (tok2), library, false , false );
716+ }
717+ return false ;
718+ }
719+
720+ static ValueFlow::Value getLifetimeIteratorValue (const Token* tok)
721+ {
722+ std::vector<ValueFlow::Value> values = getLifetimeObjValues (tok);
723+ auto it = std::find_if (values.begin (), values.end (), [](const ValueFlow::Value& v) {
724+ return v.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator;
725+ });
726+ if (it != values.end ())
727+ return *it;
728+ if (values.size () == 1 )
729+ return values.front ();
730+ return ValueFlow::Value{};
731+ }
732+
700733bool CheckStl::checkIteratorPair (const Token* tok1, const Token* tok2)
701734{
702735 if (!tok1)
703736 return false ;
704737 if (!tok2)
705738 return false ;
706- ValueFlow::Value val1 = getLifetimeObjValue (tok1);
707- ValueFlow::Value val2 = getLifetimeObjValue (tok2);
739+ ValueFlow::Value val1 = getLifetimeIteratorValue (tok1);
740+ ValueFlow::Value val2 = getLifetimeIteratorValue (tok2);
708741 if (val1.tokvalue && val2.tokvalue && val1.lifetimeKind == val2.lifetimeKind ) {
709742 if (val1.lifetimeKind == ValueFlow::Value::LifetimeKind::Lambda)
710743 return false ;
@@ -715,7 +748,7 @@ bool CheckStl::checkIteratorPair(const Token* tok1, const Token* tok2)
715748 (!astIsContainer (val1.tokvalue ) || !astIsContainer (val2.tokvalue )))
716749 return false ;
717750 }
718- if (isSameExpression ( true , false , val1.tokvalue , val2.tokvalue , mSettings ->library , false , false ))
751+ if (isSameIteratorContainerExpression ( val1.tokvalue , val2.tokvalue , mSettings ->library , val1. lifetimeKind ))
719752 return false ;
720753 if (val1.tokvalue ->expressionString () == val2.tokvalue ->expressionString ())
721754 iteratorsError (tok1, val1.tokvalue , val1.tokvalue ->expressionString ());
@@ -731,7 +764,7 @@ bool CheckStl::checkIteratorPair(const Token* tok1, const Token* tok2)
731764 }
732765 const Token* iter1 = getIteratorExpression (tok1);
733766 const Token* iter2 = getIteratorExpression (tok2);
734- if (iter1 && iter2 && !isSameExpression ( true , false , iter1, iter2, mSettings ->library , false , false )) {
767+ if (iter1 && iter2 && !isSameIteratorContainerExpression ( iter1, iter2, mSettings ->library )) {
735768 mismatchingContainerExpressionError (iter1, iter2);
736769 return true ;
737770 }
@@ -808,9 +841,11 @@ void CheckStl::mismatchingContainerIterator()
808841 for (const Token* tok = scope->bodyStart ->next (); tok != scope->bodyEnd ; tok = tok->next ()) {
809842 if (!astIsContainer (tok))
810843 continue ;
811- if (!Token::Match (tok, " %var% . %name% ( !!)" ))
844+ if (!astIsLHS (tok))
845+ continue ;
846+ if (!Token::Match (tok->astParent (), " . %name% ( !!)" ))
812847 continue ;
813- const Token * const ftok = tok->tokAt ( 2 );
848+ const Token* const ftok = tok->astParent ()-> next ( );
814849 const std::vector<const Token *> args = getArguments (ftok);
815850
816851 const Library::Container * c = tok->valueType ()->container ;
@@ -831,20 +866,14 @@ void CheckStl::mismatchingContainerIterator()
831866 continue ;
832867 }
833868
834- ValueFlow::Value val = getLifetimeObjValue (iterTok);
869+ ValueFlow::Value val = getLifetimeIteratorValue (iterTok);
835870 if (!val.tokvalue )
836871 continue ;
837872 if (val.lifetimeKind != ValueFlow::Value::LifetimeKind::Iterator)
838873 continue ;
839- for (const LifetimeToken& lt:getLifetimeTokens (tok)) {
840- if (lt.inconclusive )
841- continue ;
842- const Token* contTok = lt.token ;
843- if (isSameExpression (true , false , contTok, val.tokvalue , mSettings ->library , false , false ))
844- continue ;
845- mismatchingContainerIteratorError (tok, iterTok);
846- }
847-
874+ if (isSameIteratorContainerExpression (tok, val.tokvalue , mSettings ->library ))
875+ continue ;
876+ mismatchingContainerIteratorError (tok, iterTok);
848877 }
849878 }
850879}
0 commit comments