Fixed #4850 (False positive: invalidIterator1 detected when iterator container is member of some struct)

This commit is contained in:
Daniel Marjamäki 2013-10-26 17:48:20 +02:00
parent 853d9dd7a9
commit 8687e85e56
2 changed files with 26 additions and 1 deletions

View File

@ -57,6 +57,13 @@ void CheckStl::dereferenceErasedError(const Token *erased, const Token* deref, c
}
}
static const Token *skipMembers(const Token *tok)
{
while (Token::Match(tok, "%var% ."))
tok = tok->tokAt(2);
return tok;
}
void CheckStl::iterators()
{
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
@ -152,7 +159,8 @@ void CheckStl::iterators()
// it = foo.erase(..
// taking the result of an erase is ok
else if (Token::Match(tok2, "%varid% = %var% . erase (", iteratorId)) {
else if (Token::Match(tok2, "%varid% = %var% .", iteratorId) &&
Token::simpleMatch(skipMembers(tok2->tokAt(2)), "erase (")) {
// the returned iterator is valid
validatingToken = tok2->linkAt(5);
tok2 = tok2->tokAt(5);

View File

@ -67,6 +67,7 @@ private:
TEST_CASE(eraseAssign1);
TEST_CASE(eraseAssign2);
TEST_CASE(eraseAssign3);
TEST_CASE(eraseAssign4);
TEST_CASE(eraseAssignByFunctionCall);
TEST_CASE(eraseErase);
TEST_CASE(eraseByValue);
@ -910,6 +911,22 @@ private:
ASSERT_EQUALS("", errout.str());
}
void eraseAssign4() {
check("void f(std::list<int> data) {\n"
" std::list<int>::const_iterator it = data.begin();\n"
" it = data.erase(it);\n"
" it = data.erase(it);\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void f(Data data) {\n"
" std::list<int>::const_iterator it = data.ints.begin();\n"
" it = data.ints.erase(it);\n"
" it = data.ints.erase(it);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void eraseAssignByFunctionCall() {
check("void f(std::list<list<int> >& l) {\n"
" std::list<foo>::const_iterator i;\n"