From dc12a9b3b5ed8243ba103de811b7acb91d3485c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 15 Jun 2010 19:53:09 +0200 Subject: [PATCH] Fixed #1545 (new check: usage of iterator pointing to invalid memory after reserve) --- lib/checkstl.cpp | 6 +++--- test/teststl.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 5a0f4d7a9..a2ac2c479 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -347,7 +347,7 @@ void CheckStl::pushback() } } - // Iterator becomes invalid after push_back or push_front.. + // Iterator becomes invalid after reserve, push_back or push_front.. for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { if (!Token::simpleMatch(tok, "vector <")) @@ -422,7 +422,7 @@ void CheckStl::pushback() pushbackTok = 0; break; } - else if (Token::Match(tok3, "%varid% . push_front|push_back|insert (", varId)) + else if (Token::Match(tok3, "%varid% . push_front|push_back|insert|reserve (", varId)) { pushbackTok = tok3->tokAt(2); } @@ -448,7 +448,7 @@ void CheckStl::pushback() } // push_back on vector.. - if (vectorid > 0 && Token::Match(tok2, "%varid% . push_front|push_back|insert (", vectorid)) + if (vectorid > 0 && Token::Match(tok2, "%varid% . push_front|push_back|insert|reserve (", vectorid)) { if (!invalidIterator.empty() && Token::Match(tok2->tokAt(2), "insert ( %varid% ,", iteratorid)) { diff --git a/test/teststl.cpp b/test/teststl.cpp index af80a1a1d..72a0267c7 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -68,6 +68,7 @@ private: TEST_CASE(pushback7); TEST_CASE(pushback8); TEST_CASE(pushback9); + TEST_CASE(pushback10); TEST_CASE(insert1); @@ -661,6 +662,29 @@ private: ASSERT_EQUALS("", errout.str()); } + void pushback10() + { + check("void f(std::vector &foo)\n" + "{\n" + " std::vector::const_iterator it = foo.begin();\n" + " foo.reserve(100);\n" + " *it = 0;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5]: (error) After reserve, the iterator 'it' may be invalid\n", errout.str()); + + // in loop + check("void f()\n" + "{\n" + " std::vector foo;\n" + " foo.push_back(10);\n" + " std::vector::iterator it;\n" + " for (it = foo.begin(); it != foo.end(); ++it)\n" + " {\n" + " foo.reserve(123);\n" + " }\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:8]: (error) After reserve, the iterator 'it' may be invalid\n", errout.str()); + } void insert1()