STL: checking that containers are matching

This commit is contained in:
Daniel Marjamäki 2009-10-18 18:42:01 +02:00
parent 50e542c183
commit 0e56e4cd37
3 changed files with 46 additions and 0 deletions

View File

@ -88,6 +88,30 @@ void CheckStl::iterators()
}
// Error message for bad iterator usage..
void CheckStl::mismatchingContainersError(const Token *tok)
{
reportError(tok, Severity::error, "mismatchingContainers", "mismatching containers");
}
void CheckStl::mismatchingContainers()
{
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if (tok->str() != "std")
continue;
if (Token::Match(tok, "std :: find|find_if|count|transform|replace|replace_if|sort ( %var% . begin|rbegin ( ) , %var% . end|rend ( ) ,"))
{
if (tok->tokAt(4)->str() != tok->tokAt(10)->str())
{
mismatchingContainersError(tok);
}
}
}
}
void CheckStl::stlOutOfBounds()
{
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())

View File

@ -49,6 +49,7 @@ public:
checkStl.stlOutOfBounds();
checkStl.iterators();
checkStl.mismatchingContainers();
checkStl.erase();
checkStl.pushback();
checkStl.stlBoundries();
@ -67,6 +68,12 @@ public:
*/
void iterators();
/**
* Mismatching containers:
* std::find(foo.begin(), bar.end(), x)
*/
void mismatchingContainers();
/** Dereferencing an erased iterator */
void dereferenceErasedError(const Token *tok, const std::string &itername);
@ -96,6 +103,7 @@ private:
void stlOutOfBoundsError(const Token *tok, const std::string &num, const std::string &var);
void iteratorsError(const Token *tok, const std::string &container1, const std::string &container2);
void mismatchingContainersError(const Token *tok);
void eraseError(const Token *tok);
void pushbackError(const Token *tok, const std::string &func, const std::string &iterator_name);
void invalidPointerError(const Token *tok, const std::string &pointer_name);
@ -104,6 +112,7 @@ private:
void getErrorMessages()
{
iteratorsError(0, "container1", "container2");
mismatchingContainersError(0);
dereferenceErasedError(0, "iter");
stlOutOfBoundsError(0, "i", "foo");
eraseError(0);
@ -122,6 +131,7 @@ private:
return "Check for invalid usage of STL:\n"
" * out of bounds errors\n"
" * misuse of iterators when iterating through a container\n"
" * mismatching containers in calls\n"
" * dereferencing an erased iterator\n"
" * for vectors: using iterator/pointer after push_back has been used\n";
}

View File

@ -38,6 +38,7 @@ private:
TEST_CASE(iterator2);
TEST_CASE(iterator3);
TEST_CASE(iterator4);
TEST_CASE(iterator5);
TEST_CASE(dereference);
TEST_CASE(dereference_member);
@ -140,6 +141,17 @@ private:
ASSERT_EQUALS("", errout.str());
}
void iterator5()
{
check("void foo()\n"
"{\n"
" std::vector<int> ints1;\n"
" std::vector<int> ints2;\n"
" std::vector<int>::iterator it = std::find(ints1.begin(), ints2.end(), 22);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) mismatching containers\n", errout.str());
}
// Dereferencing invalid pointer
void dereference()
{