Skip to content

Commit 8687e85

Browse files
committed
Fixed danmar#4850 (False positive: invalidIterator1 detected when iterator container is member of some struct)
1 parent 853d9dd commit 8687e85

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

lib/checkstl.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ void CheckStl::dereferenceErasedError(const Token *erased, const Token* deref, c
5757
}
5858
}
5959

60+
static const Token *skipMembers(const Token *tok)
61+
{
62+
while (Token::Match(tok, "%var% ."))
63+
tok = tok->tokAt(2);
64+
return tok;
65+
}
66+
6067
void CheckStl::iterators()
6168
{
6269
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
@@ -152,7 +159,8 @@ void CheckStl::iterators()
152159

153160
// it = foo.erase(..
154161
// taking the result of an erase is ok
155-
else if (Token::Match(tok2, "%varid% = %var% . erase (", iteratorId)) {
162+
else if (Token::Match(tok2, "%varid% = %var% .", iteratorId) &&
163+
Token::simpleMatch(skipMembers(tok2->tokAt(2)), "erase (")) {
156164
// the returned iterator is valid
157165
validatingToken = tok2->linkAt(5);
158166
tok2 = tok2->tokAt(5);

test/teststl.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class TestStl : public TestFixture {
6767
TEST_CASE(eraseAssign1);
6868
TEST_CASE(eraseAssign2);
6969
TEST_CASE(eraseAssign3);
70+
TEST_CASE(eraseAssign4);
7071
TEST_CASE(eraseAssignByFunctionCall);
7172
TEST_CASE(eraseErase);
7273
TEST_CASE(eraseByValue);
@@ -910,6 +911,22 @@ class TestStl : public TestFixture {
910911
ASSERT_EQUALS("", errout.str());
911912
}
912913

914+
void eraseAssign4() {
915+
check("void f(std::list<int> data) {\n"
916+
" std::list<int>::const_iterator it = data.begin();\n"
917+
" it = data.erase(it);\n"
918+
" it = data.erase(it);\n"
919+
"}");
920+
ASSERT_EQUALS("", errout.str());
921+
922+
check("void f(Data data) {\n"
923+
" std::list<int>::const_iterator it = data.ints.begin();\n"
924+
" it = data.ints.erase(it);\n"
925+
" it = data.ints.erase(it);\n"
926+
"}");
927+
ASSERT_EQUALS("", errout.str());
928+
}
929+
913930
void eraseAssignByFunctionCall() {
914931
check("void f(std::list<list<int> >& l) {\n"
915932
" std::list<foo>::const_iterator i;\n"

0 commit comments

Comments
 (0)