Fixed handling of std::vector::insert() in CheckStl::pushback()

This commit is contained in:
PKEuS 2013-03-04 02:57:09 -08:00
parent c24527dbde
commit 34b1d75a10
2 changed files with 32 additions and 3 deletions

View File

@ -638,7 +638,7 @@ void CheckStl::pushback()
if (tok3->str() == "break" || tok3->str() == "return") { if (tok3->str() == "break" || tok3->str() == "return") {
pushbackTok = 0; pushbackTok = 0;
break; 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); pushbackTok = tok3->tokAt(2);
} }
} }
@ -649,9 +649,13 @@ void CheckStl::pushback()
// Assigning iterator.. // Assigning iterator..
if (Token::Match(tok2, "%varid% =", iteratorid)) { 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(); vectorid = tok2->tokAt(2)->varId();
tok2 = tok2->tokAt(6); tok2 = tok2->linkAt(5);
} else { } else {
vectorid = 0; vectorid = 0;
} }

View File

@ -1161,6 +1161,31 @@ private:
" return i->foo;\n" " return i->foo;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (error) After insert(), the iterator 'i' may be invalid.\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) After insert(), the iterator 'i' may be invalid.\n", errout.str());
check("void f(const std::vector<Bar>& bars) {\n"
" for(std::vector<Bar>::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<Bar>& bars) {\n"
" for(std::vector<Bar>::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<Bar>& bars) {\n"
" std::vector<Bar>::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() { void insert2() {