diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 7f83ba0cf..c970d225f 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -621,6 +621,13 @@ bool CheckStl::checkIteratorPair(const Token* tok1, const Token* tok2) if (val1.tokvalue && val2.tokvalue && val1.lifetimeKind == val2.lifetimeKind) { if (val1.lifetimeKind == ValueFlow::Value::LifetimeKind::Lambda) return false; + if (tok1->astParent() == tok2->astParent() && Token::Match(tok1->astParent(), "%comp%|-")) { + if (val1.lifetimeKind == ValueFlow::Value::LifetimeKind::Address) + return false; + if (val1.lifetimeKind == ValueFlow::Value::LifetimeKind::Object && + (!astIsContainer(val1.tokvalue) || !astIsContainer(val2.tokvalue))) + return false; + } if (isSameExpression(true, false, val1.tokvalue, val2.tokvalue, mSettings->library, false, false)) return false; if (val1.tokvalue->expressionString() == val2.tokvalue->expressionString()) diff --git a/test/teststl.cpp b/test/teststl.cpp index 00fb7b9f5..f857d1e31 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -66,6 +66,7 @@ private: TEST_CASE(iterator21); TEST_CASE(iterator22); TEST_CASE(iterator23); + TEST_CASE(iterator24); TEST_CASE(iteratorExpression); TEST_CASE(iteratorSameExpression); @@ -1072,6 +1073,36 @@ private: ASSERT_EQUALS("", errout.str()); } + void iterator24() + { // #9556 + check("void f(int a, int b) {\n" + " if (&a == &b) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f(int a, int b) {\n" + " if (std::for_each(&a, &b + 1, [](auto) {})) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (error) Iterators of different containers 'a' and 'b' are used together.\n", + errout.str()); + + check("void f(int a, int b) {\n" + " if (std::for_each(&a, &b, [](auto) {})) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (error) Iterators of different containers 'a' and 'b' are used together.\n", + errout.str()); + + check("void f(int a) {\n" + " if (std::for_each(&a, &a, [](auto) {})) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (style) Same iterators expression are used for algorithm.\n", errout.str()); + + check("void f(int a) {\n" + " if (std::for_each(&a, &a + 1, [](auto) {})) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void iteratorExpression() { check("std::vector& f();\n" "std::vector& g();\n"