@@ -854,30 +854,26 @@ struct InvalidContainerAnalyzer {
854854 };
855855 std::unordered_map<int , Reference> expressions;
856856 ErrorPath errorPath;
857- void add (const std::vector<Reference>& refs)
858- {
857+ void add (const std::vector<Reference>& refs) {
859858 for (const Reference& r : refs) {
860859 add (r);
861860 }
862861 }
863- void add (const Reference& r)
864- {
862+ void add (const Reference& r) {
865863 if (!r.tok )
866864 return ;
867865 expressions.insert (std::make_pair (r.tok ->exprId (), r));
868866 }
869867
870- std::vector<Reference> invalidTokens () const
871- {
868+ std::vector<Reference> invalidTokens () const {
872869 std::vector<Reference> result;
873870 std::transform (expressions.begin (), expressions.end (), std::back_inserter (result), SelectMapValues{});
874871 return result;
875872 }
876873 };
877874 std::unordered_map<const Function*, Info> invalidMethods;
878875
879- std::vector<Info::Reference> invalidatesContainer (const Token* tok) const
880- {
876+ std::vector<Info::Reference> invalidatesContainer (const Token* tok) const {
881877 std::vector<Info::Reference> result;
882878 if (Token::Match (tok, " %name% (" )) {
883879 const Function* f = tok->function ();
@@ -920,15 +916,14 @@ struct InvalidContainerAnalyzer {
920916 ErrorPath ep;
921917 ep.emplace_front (tok,
922918 " After calling '" + tok->strAt (2 ) +
923- " ', iterators or references to the container's data may be invalid ." );
919+ " ', iterators or references to the container's data may be invalid ." );
924920 result.push_back (Info::Reference{tok, ep});
925921 }
926922 }
927923 return result;
928924 }
929925
930- void analyze (const SymbolDatabase* symboldatabase)
931- {
926+ void analyze (const SymbolDatabase* symboldatabase) {
932927 for (const Scope* scope : symboldatabase->functionScopes ) {
933928 const Function* f = scope->function ;
934929 if (!f)
@@ -990,55 +985,55 @@ void CheckStl::invalidContainer()
990985 const ValueFlow::Value* v = nullptr ;
991986 ErrorPath errorPath;
992987 PathAnalysis::Info info =
993- PathAnalysis{endToken, library}.forwardFind ([&](const PathAnalysis::Info& info) {
994- if (!info.tok ->variable ())
995- return false ;
996- if (info.tok ->varId () == 0 )
997- return false ;
998- if (skipVarIds.count (info.tok ->varId ()) > 0 )
999- return false ;
1000- // if (Token::simpleMatch(info.tok->next(), "."))
1001- // return false;
1002- if (Token::Match (info.tok ->astParent (), " %assign%" ) && astIsLHS (info.tok ))
1003- skipVarIds.insert (info.tok ->varId ());
1004- if (info.tok ->variable ()->isReference () && !isVariableDecl (info.tok ) &&
1005- reaches (info.tok ->variable ()->nameToken (), tok, library, nullptr )) {
1006-
1007- ErrorPath ep;
1008- bool addressOf = false ;
1009- const Variable* var = getLifetimeVariable (info.tok , ep, &addressOf);
1010- // Check the reference is created before the change
1011- if (var && var->declarationId () == r.tok ->varId () && !addressOf) {
1012- // An argument always reaches
1013- if (var->isArgument () ||
1014- (!var->isReference () && !var->isRValueReference () && !isVariableDecl (tok) &&
1015- reaches (var->nameToken (), tok, library, &ep))) {
1016- errorPath = ep;
1017- return true ;
1018- }
1019- }
1020- }
1021- for (const ValueFlow::Value& val : info.tok ->values ()) {
1022- if (!val.isLocalLifetimeValue ())
1023- continue ;
1024- if (val.lifetimeKind == ValueFlow::Value::LifetimeKind::Address)
1025- continue ;
1026- if (val.lifetimeKind == ValueFlow::Value::LifetimeKind::SubObject)
1027- continue ;
1028- if (!val.tokvalue ->variable ())
1029- continue ;
1030- if (val.tokvalue ->varId () != r.tok ->varId ())
1031- continue ;
1032- ErrorPath ep;
1033- // Check the iterator is created before the change
1034- if (val.tokvalue != tok && reaches (val.tokvalue , tok, library, &ep)) {
1035- v = &val;
988+ PathAnalysis{endToken, library} .forwardFind ([&](const PathAnalysis::Info& info) {
989+ if (!info.tok ->variable ())
990+ return false ;
991+ if (info.tok ->varId () == 0 )
992+ return false ;
993+ if (skipVarIds.count (info.tok ->varId ()) > 0 )
994+ return false ;
995+ // if (Token::simpleMatch(info.tok->next(), "."))
996+ // return false;
997+ if (Token::Match (info.tok ->astParent (), " %assign%" ) && astIsLHS (info.tok ))
998+ skipVarIds.insert (info.tok ->varId ());
999+ if (info.tok ->variable ()->isReference () && !isVariableDecl (info.tok ) &&
1000+ reaches (info.tok ->variable ()->nameToken (), tok, library, nullptr )) {
1001+
1002+ ErrorPath ep;
1003+ bool addressOf = false ;
1004+ const Variable* var = getLifetimeVariable (info.tok , ep, &addressOf);
1005+ // Check the reference is created before the change
1006+ if (var && var->declarationId () == r.tok ->varId () && !addressOf) {
1007+ // An argument always reaches
1008+ if (var->isArgument () ||
1009+ (!var->isReference () && !var->isRValueReference () && !isVariableDecl (tok) &&
1010+ reaches (var->nameToken (), tok, library, &ep))) {
10361011 errorPath = ep;
10371012 return true ;
10381013 }
10391014 }
1040- return false ;
1041- });
1015+ }
1016+ for (const ValueFlow::Value& val : info.tok ->values ()) {
1017+ if (!val.isLocalLifetimeValue ())
1018+ continue ;
1019+ if (val.lifetimeKind == ValueFlow::Value::LifetimeKind::Address)
1020+ continue ;
1021+ if (val.lifetimeKind == ValueFlow::Value::LifetimeKind::SubObject)
1022+ continue ;
1023+ if (!val.tokvalue ->variable ())
1024+ continue ;
1025+ if (val.tokvalue ->varId () != r.tok ->varId ())
1026+ continue ;
1027+ ErrorPath ep;
1028+ // Check the iterator is created before the change
1029+ if (val.tokvalue != tok && reaches (val.tokvalue , tok, library, &ep)) {
1030+ v = &val;
1031+ errorPath = ep;
1032+ return true ;
1033+ }
1034+ }
1035+ return false ;
1036+ });
10421037 if (!info.tok )
10431038 continue ;
10441039 errorPath.insert (errorPath.end (), info.errorPath .begin (), info.errorPath .end ());
0 commit comments