STL: checking that containers are matching
This commit is contained in:
parent
50e542c183
commit
0e56e4cd37
|
@ -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())
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue