From ffbf8e38acab96930d8c53ed1ba6ab25a8ed3ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 15 Oct 2009 21:29:56 +0200 Subject: [PATCH] stl: after vector::insert, iterators may become invalid --- src/checkstl.cpp | 24 ++++++++++++------------ src/checkstl.h | 6 +++--- test/teststl.cpp | 14 +++++++------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/checkstl.cpp b/src/checkstl.cpp index d4272f7ea..a490e8e5e 100644 --- a/src/checkstl.cpp +++ b/src/checkstl.cpp @@ -299,7 +299,7 @@ void CheckStl::pushback() std::string vectorname; int indent = 0; - bool invalidIterator = false; + std::string invalidIterator; for (const Token *tok2 = tok; indent >= 0 && tok2; tok2 = tok2->next()) { if (tok2->str() == "{" || tok2->str() == "(") @@ -341,14 +341,14 @@ void CheckStl::pushback() pushback = 0; break; } - else if (Token::Match(tok3, "%varid% . push_front|push_back (", vectorid)) + else if (Token::Match(tok3, "%varid% . push_front|push_back|insert (", vectorid)) { - pushback = tok3; + pushback = tok3->tokAt(2); } } if (pushback) - pushbackError(pushback, tok2->strAt(0)); + pushbackError(pushback, pushback->str(), tok2->strAt(0)); } // Assigning iterator.. @@ -358,20 +358,20 @@ void CheckStl::pushback() vectorname = tok2->strAt(2); else vectorname = ""; - invalidIterator = false; + invalidIterator = ""; } // push_back on vector.. - if (vectorname.size() && Token::Match(tok2, (vectorname + " . push_front|push_back").c_str())) - invalidIterator = true; + if (vectorname.size() && Token::Match(tok2, (vectorname + " . push_front|push_back|insert").c_str())) + invalidIterator = tok2->strAt(2); // Using invalid iterator.. - if (invalidIterator) + if (!invalidIterator.empty()) { if (Token::Match(tok2, "++|--|*|+|-|(|,|=|!= %varid%", iteratorid)) - pushbackError(tok2, tok2->strAt(1)); + pushbackError(tok2, invalidIterator, tok2->strAt(1)); if (Token::Match(tok2, "%varid% ++|--|+|-", iteratorid)) - pushbackError(tok2, tok2->str()); + pushbackError(tok2, invalidIterator, tok2->str()); } } } @@ -381,9 +381,9 @@ void CheckStl::pushback() // Error message for bad iterator usage.. -void CheckStl::pushbackError(const Token *tok, const std::string &iterator_name) +void CheckStl::pushbackError(const Token *tok, const std::string &func, const std::string &iterator_name) { - reportError(tok, Severity::error, "pushback", "After push_back or push_front, the iterator '" + iterator_name + "' may be invalid"); + reportError(tok, Severity::error, "pushback", "After " + func + ", the iterator '" + iterator_name + "' may be invalid"); } diff --git a/src/checkstl.h b/src/checkstl.h index 9c2254fc7..9a44ec042 100644 --- a/src/checkstl.h +++ b/src/checkstl.h @@ -76,7 +76,7 @@ public: void erase(); /** - * Dangerous usage of push_back + * Dangerous usage of push_back and insert */ void pushback(); @@ -97,7 +97,7 @@ private: void stlOutOfBoundsError(const Token *tok, const std::string &num, const std::string &var); void iteratorsError(const Token *tok, const std::string &container1, const std::string &container2); void eraseError(const Token *tok); - void pushbackError(const Token *tok, const std::string &iterator_name); + void pushbackError(const Token *tok, const std::string &func, const std::string &iterator_name); void invalidPointerError(const Token *tok, const std::string &pointer_name); void stlBoundriesError(const Token *tok, const std::string &container_name); @@ -107,7 +107,7 @@ private: dereferenceErasedError(0, "iter"); stlOutOfBoundsError(0, "i", "foo"); eraseError(0); - pushbackError(0, "iterator"); + pushbackError(0, "push_back|push_front|insert", "iterator"); invalidPointerError(0, "pointer"); stlBoundriesError(0, "container"); } diff --git a/test/teststl.cpp b/test/teststl.cpp index a8da29004..e33b8a29b 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -342,7 +342,7 @@ private: " foo.push_back(123);\n" " *it;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:5]: (error) After push_back or push_front, the iterator 'it' may be invalid\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5]: (error) After push_back, the iterator 'it' may be invalid\n", errout.str()); } void pushback2() @@ -371,7 +371,7 @@ private: " foo.push_back(123);\n" " }\n" "}\n"); - ASSERT_EQUALS("[test.cpp:8]: (error) After push_back or push_front, the iterator 'it' may be invalid\n", errout.str()); + ASSERT_EQUALS("[test.cpp:8]: (error) After push_back, the iterator 'it' may be invalid\n", errout.str()); } void pushback4() @@ -419,7 +419,7 @@ private: " v.push_back(10);\n" " }\n" "}\n"); - ASSERT_EQUALS("[test.cpp:9]: (error) After push_back or push_front, the iterator 'it' may be invalid\n", errout.str()); + ASSERT_EQUALS("[test.cpp:9]: (error) After push_back, the iterator 'it' may be invalid\n", errout.str()); check("void f()\n" "{\n" @@ -432,7 +432,7 @@ private: " v.push_back(10);\n" " }\n" "}\n"); - ASSERT_EQUALS("[test.cpp:9]: (error) After push_back or push_front, the iterator 'it' may be invalid\n", errout.str()); + ASSERT_EQUALS("[test.cpp:9]: (error) After push_back, the iterator 'it' may be invalid\n", errout.str()); } void pushback7() @@ -447,7 +447,7 @@ private: " foo.push_back(123);\n" " }\n" "}\n"); - ASSERT_EQUALS("[test.cpp:8]: (error) After push_back or push_front, the iterator 'it' may be invalid\n", errout.str()); + ASSERT_EQUALS("[test.cpp:8]: (error) After push_back, the iterator 'it' may be invalid\n", errout.str()); } void pushback8() @@ -464,7 +464,7 @@ private: " sum += *it;\n" " }\n" "}\n"); - ASSERT_EQUALS("[test.cpp:8]: (error) After push_back or push_front, the iterator 'end' may be invalid\n", errout.str()); + ASSERT_EQUALS("[test.cpp:8]: (error) After push_back, the iterator 'end' may be invalid\n", errout.str()); } @@ -476,7 +476,7 @@ private: " ints.insert(ints.begin(), 1);\n" " ++iter;\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:7]: (error) Invalid iterator 'iter' after insert\n", errout.str()); + ASSERT_EQUALS("[test.cpp:5]: (error) After insert, the iterator 'iter' may be invalid\n", errout.str()); }