Fixed #3210 (STL check: Add support for reverse iterator)

This commit is contained in:
Thomas Jarosch 2011-10-14 19:54:20 +02:00 committed by Daniel Marjamäki
parent 7ae39f13cc
commit 7824e5c0f5
2 changed files with 27 additions and 6 deletions

View File

@ -50,7 +50,7 @@ void CheckStl::iterators()
// for (it = foo.begin(); it != bar.end(); ++it)
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
// Locate an iterator..
if (!Token::Match(tok, "%var% = %var% . begin ( ) ;|+"))
if (!Token::Match(tok, "%var% = %var% . begin|rbegin ( ) ;|+"))
continue;
// Get variable ids for both the iterator and container
@ -77,7 +77,7 @@ void CheckStl::iterators()
break;
// Is iterator compared against different container?
if (Token::Match(tok2, "%varid% != %var% . end ( )", iteratorId) && tok2->tokAt(2)->varId() != containerId) {
if (Token::Match(tok2, "%varid% != %var% . end|rend ( )", iteratorId) && tok2->tokAt(2)->varId() != containerId) {
iteratorsError(tok2, tok->strAt(2), tok2->strAt(2));
tok2 = tok2->tokAt(6);
}
@ -404,7 +404,7 @@ void CheckStl::erase()
break;
}
if (Token::Match(tok2, "%var% = %var% . begin ( ) ; %var% != %var% . end ( )") &&
if (Token::Match(tok2, "%var% = %var% . begin|rbegin ( ) ; %var% != %var% . end|rend ( )") &&
tok2->str() == tok2->tokAt(8)->str() &&
tok2->tokAt(2)->str() == tok2->tokAt(10)->str()) {
EraseCheckLoop::checkScope(this, tok2);
@ -523,7 +523,7 @@ void CheckStl::pushback()
tok2 = tok2->tokAt(2);
}
if (Token::Match(tok2, "%varid% = %var% . begin ( ) ; %varid% != %var% . end ( ) ; ++| %varid% ++| ) {", iteratorid)) {
if (Token::Match(tok2, "%varid% = %var% . begin|rbegin ( ) ; %varid% != %var% . end|rend ( ) ; ++| %varid% ++| ) {", iteratorid)) {
// variable id for the loop iterator
const unsigned int varId(tok2->tokAt(2)->varId());
if (varId == 0)
@ -822,7 +822,7 @@ void CheckStl::sizeError(const Token *tok)
void CheckStl::redundantCondition()
{
const char pattern[] = "if ( %var% . find ( %any% ) != %var% . end ( ) ) "
const char pattern[] = "if ( %var% . find ( %any% ) != %var% . end|rend ( ) ) "
"{|{|"
" %var% . remove ( %any% ) ; "
"}|}|";
@ -864,7 +864,7 @@ void CheckStl::missingComparison()
if (tok2->str() == ";")
break;
if (!Token::Match(tok2, "%var% = %var% . begin ( ) ; %var% != %var% . end ( ) ; ++| %var% ++| ) {"))
if (!Token::Match(tok2, "%var% = %var% . begin|rbegin ( ) ; %var% != %var% . end|rend ( ) ; ++| %var% ++| ) {"))
continue;
// same iterator name

View File

@ -140,6 +140,16 @@ private:
" { }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Same iterator is used with both l1 and l2\n", errout.str());
// Same check with reverse iterator
check("void f()\n"
"{\n"
" list<int> l1;\n"
" list<int> l2;\n"
" for (list<int>::const_reverse_iterator it = l1.rbegin(); it != l2.rend(); ++it)\n"
" { }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Same iterator is used with both l1 and l2\n", errout.str());
}
void iterator2() {
@ -294,6 +304,17 @@ private:
" std::cout << iter->first << std::endl;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:7]: (error) Dereferenced iterator 'iter' has been erased\n", errout.str());
// Reverse iterator
check("void f()\n"
"{\n"
" std::map<int, int> ints;\n"
" std::map<int, int>::reverse_iterator iter;\n"
" iter = ints.rbegin();\n"
" ints.erase(iter);\n"
" std::cout << iter->first << std::endl;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:7]: (error) Dereferenced iterator 'iter' has been erased\n", errout.str());
}