STL: added check for dangerous usage of std::find (#829)

This commit is contained in:
Daniel Marjamäki 2009-11-02 20:24:38 +01:00
parent 8d57cef7f9
commit df3ffa2eda
3 changed files with 54 additions and 1 deletions

View File

@ -482,3 +482,35 @@ void CheckStl::stlBoundriesError(const Token *tok, const std::string &container_
{ {
reportError(tok, Severity::error, "stlBoundries", container_name + " range check should use != and not < since the order of the pointers isn't guaranteed"); reportError(tok, Severity::error, "stlBoundries", container_name + " range check should use != and not < since the order of the pointers isn't guaranteed");
} }
void CheckStl::find()
{
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if (tok->str() != ";")
continue;
if (!Token::Match(tok->next(), "%var% = std :: find ("))
continue;
const unsigned int iteratorid = tok->next()->varId();
if (iteratorid == 0)
continue;
tok = tok->tokAt(6)->link();
if (!tok)
break;
for (const Token *tok2 = tok; tok2; tok2 = tok2->next())
{
if (tok2->str() == "{" || tok2->str() == "}" || tok2->str() == "(" || tok2->str() == ")")
break;
if (tok2->varId() == iteratorid && Token::simpleMatch(tok2->previous(), "*"))
findError(tok2);
}
}
}
void CheckStl::findError(const Token *tok)
{
reportError(tok, Severity::error, "stlfind", "dangerous usage of find result");
}

View File

@ -53,6 +53,7 @@ public:
checkStl.erase(); checkStl.erase();
checkStl.pushback(); checkStl.pushback();
checkStl.stlBoundries(); checkStl.stlBoundries();
checkStl.find();
} }
@ -92,6 +93,9 @@ public:
*/ */
void stlBoundries(); void stlBoundries();
/** usage of std::find */
void find();
private: private:
/** /**
@ -108,6 +112,7 @@ private:
void invalidIteratorError(const Token *tok, const std::string &func, const std::string &iterator_name); void invalidIteratorError(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);
void stlBoundriesError(const Token *tok, const std::string &container_name); void stlBoundriesError(const Token *tok, const std::string &container_name);
void findError(const Token *tok);
void getErrorMessages() void getErrorMessages()
{ {
@ -119,6 +124,7 @@ private:
invalidIteratorError(0, "push_back|push_front|insert", "iterator"); invalidIteratorError(0, "push_back|push_front|insert", "iterator");
invalidPointerError(0, "pointer"); invalidPointerError(0, "pointer");
stlBoundriesError(0, "container"); stlBoundriesError(0, "container");
findError(0);
} }
std::string name() const std::string name() const
@ -133,7 +139,8 @@ private:
" * misuse of iterators when iterating through a container\n" " * misuse of iterators when iterating through a container\n"
" * mismatching containers in calls\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"
" * dangerous usage of find";
} }
}; };
/// @} /// @}

View File

@ -68,6 +68,9 @@ private:
TEST_CASE(stlBoundries1); TEST_CASE(stlBoundries1);
TEST_CASE(stlBoundries2); TEST_CASE(stlBoundries2);
TEST_CASE(stlBoundries3); TEST_CASE(stlBoundries3);
// find
TEST_CASE(find1);
} }
void check(const char code[]) void check(const char code[])
@ -571,6 +574,17 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void find1()
{
check("void f(std::vector<int> &ints)\n"
"{\n"
" std::vector<int>::iterator it = std::find(ints.begin(), ints.end(), 33);\n"
" *it = 11;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
}; };
REGISTER_TEST(TestStl) REGISTER_TEST(TestStl)