STL: added check for dangerous usage of std::find (#829)
This commit is contained in:
parent
8d57cef7f9
commit
df3ffa2eda
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
checkStl.erase();
|
||||
checkStl.pushback();
|
||||
checkStl.stlBoundries();
|
||||
checkStl.find();
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,6 +92,9 @@ public:
|
|||
* bad condition.. "it < alist.end()"
|
||||
*/
|
||||
void stlBoundries();
|
||||
|
||||
/** usage of std::find */
|
||||
void find();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -108,6 +112,7 @@ private:
|
|||
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 stlBoundriesError(const Token *tok, const std::string &container_name);
|
||||
void findError(const Token *tok);
|
||||
|
||||
void getErrorMessages()
|
||||
{
|
||||
|
@ -119,6 +124,7 @@ private:
|
|||
invalidIteratorError(0, "push_back|push_front|insert", "iterator");
|
||||
invalidPointerError(0, "pointer");
|
||||
stlBoundriesError(0, "container");
|
||||
findError(0);
|
||||
}
|
||||
|
||||
std::string name() const
|
||||
|
@ -133,7 +139,8 @@ private:
|
|||
" * 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";
|
||||
" * for vectors: using iterator/pointer after push_back has been used\n"
|
||||
" * dangerous usage of find";
|
||||
}
|
||||
};
|
||||
/// @}
|
||||
|
|
|
@ -68,6 +68,9 @@ private:
|
|||
TEST_CASE(stlBoundries1);
|
||||
TEST_CASE(stlBoundries2);
|
||||
TEST_CASE(stlBoundries3);
|
||||
|
||||
// find
|
||||
TEST_CASE(find1);
|
||||
}
|
||||
|
||||
void check(const char code[])
|
||||
|
@ -571,6 +574,17 @@ private:
|
|||
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)
|
||||
|
|
Loading…
Reference in New Issue