From 34b1d75a10cd49cd09909f372617df3427c241f8 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Mon, 4 Mar 2013 02:57:09 -0800 Subject: [PATCH] Fixed handling of std::vector::insert() in CheckStl::pushback() --- lib/checkstl.cpp | 10 +++++++--- test/teststl.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index c07a7c0bc..ab2834471 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -638,7 +638,7 @@ void CheckStl::pushback() if (tok3->str() == "break" || tok3->str() == "return") { pushbackTok = 0; break; - } else if (Token::Match(tok3, "%varid% . push_front|push_back|insert|reserve|resize|clear (", varId)) { + } else if (Token::Match(tok3, "%varid% . push_front|push_back|insert|reserve|resize|clear (", varId) && !tok3->previous()->isAssignmentOp()) { pushbackTok = tok3->tokAt(2); } } @@ -649,9 +649,13 @@ void CheckStl::pushback() // Assigning iterator.. if (Token::Match(tok2, "%varid% =", iteratorid)) { - if (Token::Match(tok2->tokAt(2), "%var% . begin|end|rbegin|rend|cbegin|cend|crbegin|crend ( )")) { + if (Token::Match(tok2->tokAt(2), "%var% . begin|end|rbegin|rend|cbegin|cend|crbegin|crend|insert (")) { + if (!invalidIterator.empty() && Token::Match(tok2->tokAt(4), "insert ( %varid% ,", iteratorid)) { + invalidIteratorError(tok2, invalidIterator, tok2->strAt(6)); + break; + } vectorid = tok2->tokAt(2)->varId(); - tok2 = tok2->tokAt(6); + tok2 = tok2->linkAt(5); } else { vectorid = 0; } diff --git a/test/teststl.cpp b/test/teststl.cpp index bf9a908aa..712c6f810 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -1161,6 +1161,31 @@ private: " return i->foo;\n" "}"); ASSERT_EQUALS("[test.cpp:4]: (error) After insert(), the iterator 'i' may be invalid.\n", errout.str()); + + check("void f(const std::vector& bars) {\n" + " for(std::vector::iterator i = bars.begin(); i != bars.end(); ++i) {\n" + " i = bars.insert(i, bar);\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void f(const std::vector& bars) {\n" + " for(std::vector::iterator i = bars.begin(); i != bars.end(); ++i) {\n" + " bars.insert(i, bar);\n" + " i = bars.insert(i, bar);\n" + " }\n" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (error) After insert(), the iterator 'i' may be invalid.\n" + "[test.cpp:4]: (error) After insert(), the iterator 'i' may be invalid.\n", errout.str()); + + check("void* f(const std::vector& bars) {\n" + " std::vector::iterator i = bars.begin();\n" + " bars.insert(i, Bar());\n" + " i = bars.insert(i, Bar());\n" + " void* v = &i->foo;\n" + " return v;\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (error) After insert(), the iterator 'i' may be invalid.\n", errout.str()); } void insert2() {