Fixed #1656 (dangerous usage of erase not detected: for (; it != it2; ++it) ints.erase(it);)
This commit is contained in:
parent
2901434773
commit
8971d697b2
|
@ -204,8 +204,19 @@ void CheckStl::erase()
|
||||||
{
|
{
|
||||||
if (Token::simpleMatch(tok, "for ("))
|
if (Token::simpleMatch(tok, "for ("))
|
||||||
{
|
{
|
||||||
for (const Token *tok2 = tok->tokAt(2); tok2 && tok2->str() != ";"; tok2 = tok2->next())
|
for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next())
|
||||||
{
|
{
|
||||||
|
if (tok2->str() == ";")
|
||||||
|
{
|
||||||
|
if (Token::Match(tok2, "; %var% !="))
|
||||||
|
{
|
||||||
|
const unsigned int varid = tok2->next()->varId();
|
||||||
|
if (varid > 0 && Token::findmatch(_tokenizer->tokens(), "> :: iterator %varid%", varid))
|
||||||
|
eraseCheckLoop(tok2->next());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (Token::Match(tok2, "%var% = %var% . begin ( ) ; %var% != %var% . end ( ) ") &&
|
if (Token::Match(tok2, "%var% = %var% . begin ( ) ; %var% != %var% . end ( ) ") &&
|
||||||
tok2->str() == tok2->tokAt(8)->str() &&
|
tok2->str() == tok2->tokAt(8)->str() &&
|
||||||
tok2->tokAt(2)->str() == tok2->tokAt(10)->str())
|
tok2->tokAt(2)->str() == tok2->tokAt(10)->str())
|
||||||
|
@ -216,9 +227,11 @@ void CheckStl::erase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::Match(tok, "while ( %var% != %var% . end ( )"))
|
if (Token::Match(tok, "while ( %var% !="))
|
||||||
{
|
{
|
||||||
eraseCheckLoop(tok->tokAt(2));
|
const unsigned int varid = tok->tokAt(2)->varId();
|
||||||
|
if (varid > 0 && Token::findmatch(_tokenizer->tokens(), "> :: iterator %varid%", varid))
|
||||||
|
eraseCheckLoop(tok->tokAt(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ private:
|
||||||
TEST_CASE(erase);
|
TEST_CASE(erase);
|
||||||
TEST_CASE(erase2);
|
TEST_CASE(erase2);
|
||||||
TEST_CASE(erase3);
|
TEST_CASE(erase3);
|
||||||
|
TEST_CASE(erase4);
|
||||||
TEST_CASE(eraseBreak);
|
TEST_CASE(eraseBreak);
|
||||||
TEST_CASE(eraseReturn);
|
TEST_CASE(eraseReturn);
|
||||||
TEST_CASE(eraseGoto);
|
TEST_CASE(eraseGoto);
|
||||||
|
@ -376,6 +377,39 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void erase4()
|
||||||
|
{
|
||||||
|
check("void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" std::list<int>::iterator it, it2;\n"
|
||||||
|
" for (it = foo.begin(); it != i2; ++it)\n"
|
||||||
|
" {\n"
|
||||||
|
" foo.erase(it);\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:6]: (error) Dangerous iterator usage. After erase the iterator is invalid so dereferencing it or comparing it with another iterator is invalid.\n", errout.str());
|
||||||
|
|
||||||
|
check("void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" std::list<int>::iterator it = foo.begin();\n"
|
||||||
|
" for (; it != i2; ++it)\n"
|
||||||
|
" {\n"
|
||||||
|
" foo.erase(it);\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:6]: (error) Dangerous iterator usage. After erase the iterator is invalid so dereferencing it or comparing it with another iterator is invalid.\n", errout.str());
|
||||||
|
|
||||||
|
check("void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" std::list<int>::iterator it = foo.begin();\n"
|
||||||
|
" while (it != i2)\n"
|
||||||
|
" {\n"
|
||||||
|
" foo.erase(it);\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:6]: (error) Dangerous iterator usage. After erase the iterator is invalid so dereferencing it or comparing it with another iterator is invalid.\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void eraseBreak()
|
void eraseBreak()
|
||||||
{
|
{
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
|
|
Loading…
Reference in New Issue