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() void CheckStl::stlOutOfBounds()
{ {
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())

View File

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