Diagnose mismatching iterators used together in operators (#1343)

* Diagnose mismatching iterators used together in operators

* Fix fp getting iterator expression in function call
This commit is contained in:
Paul Fultz II 2018-08-20 23:34:30 -05:00 committed by Daniel Marjamäki
parent 866d198756
commit f79849f6ba
2 changed files with 48 additions and 1 deletions

View File

@ -466,6 +466,8 @@ static const Token * getIteratorExpression(const Token * tok)
const Token *iter1 = getIteratorExpression(tok->astOperand1());
if (iter1)
return iter1;
if(tok->str() == "(")
return nullptr;
const Token *iter2 = getIteratorExpression(tok->astOperand2());
if (iter2)
return iter2;
@ -484,6 +486,14 @@ void CheckStl::mismatchingContainers()
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) {
for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) {
if(Token::Match(tok, "%comp%|-")) {
const Token * iter1 = getIteratorExpression(tok->astOperand1());
const Token * iter2 = getIteratorExpression(tok->astOperand2());
if (iter1 && iter2 && !isSameExpression(true, false, iter1, iter2, mSettings->library, false)) {
mismatchingContainerExpressionError(iter1, iter2);
continue;
}
}
if (!Token::Match(tok, "%name% ( !!)"))
continue;
const Token * const ftok = tok;

View File

@ -607,6 +607,20 @@ private:
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) Iterators to containers from different expressions 'f()' and 'g()' are used together.\n", errout.str());
check("std::vector<int>& f();\n"
"std::vector<int>& g();\n"
"void foo() {\n"
" if(f().begin() == g().end()) {}\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) Iterators to containers from different expressions 'f()' and 'g()' are used together.\n", errout.str());
check("std::vector<int>& f();\n"
"std::vector<int>& g();\n"
"void foo() {\n"
" auto size = f().end() - g().begin();\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (warning) Iterators to containers from different expressions 'f()' and 'g()' are used together.\n", errout.str());
check("struct A {\n"
" std::vector<int>& f();\n"
" std::vector<int>& g();\n"
@ -644,7 +658,20 @@ private:
check("std::vector<int>& f();\n"
"std::vector<int>& g();\n"
"void foo() {\n"
" auto it = f().end();"
" if(bar(f().begin()) == g().end()) {}\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("std::vector<int>& f();\n"
"std::vector<int>& g();\n"
"void foo() {\n"
" auto it = f().end();\n"
" f().begin() - it\n"
" f().begin()+1 - it\n"
" f().begin() - (it + 1)\n"
" f().begin() - f().end()\n"
" f().begin()+1 - f().end()\n"
" f().begin() - (f().end() + 1)\n"
" (void)std::find(f().begin(), it, 0);\n"
" (void)std::find(f().begin(), it + 1, 0);\n"
" (void)std::find(f().begin() + 1, it + 1, 0);\n"
@ -659,6 +686,16 @@ private:
" (void)std::find(begin(f()) + 1, end(f()) - 1, 0);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("std::vector<int>& f();\n"
"std::vector<int>& g();\n"
"void foo() {\n"
" if(f().begin() == f().end()) {}\n"
" if(f().begin() == f().end()+1) {}\n"
" if(f().begin()+1 == f().end()) {}\n"
" if(f().begin()+1 == f().end()+1) {}\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void iteratorSameExpression() {