diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 5a4a5403679..f1755fcadd3 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -727,12 +727,18 @@ static bool isSameIteratorContainerExpression(const Token* tok1, static ValueFlow::Value getLifetimeIteratorValue(const Token* tok, MathLib::bigint path = 0) { + auto findIterVal = [](const std::vector& values, const std::vector::const_iterator beg) { + return std::find_if(beg, values.cend(), [](const ValueFlow::Value& v) { + return v.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator; + }); + }; std::vector values = ValueFlow::getLifetimeObjValues(tok, false, path); - auto it = std::find_if(values.cbegin(), values.cend(), [](const ValueFlow::Value& v) { - return v.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator; - }); - if (it != values.end()) - return *it; + auto it = findIterVal(values, values.begin()); + if (it != values.end()) { + auto it2 = findIterVal(values, it + 1); + if (it2 == values.cend()) + return *it; + } if (values.size() == 1) return values.front(); return ValueFlow::Value{}; diff --git a/test/teststl.cpp b/test/teststl.cpp index 8e3b9d5bde3..75b8b659786 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -69,6 +69,7 @@ class TestStl : public TestFixture { TEST_CASE(iterator27); // #10378 TEST_CASE(iterator28); // #10450 TEST_CASE(iterator29); + TEST_CASE(iterator30); TEST_CASE(iteratorExpression); TEST_CASE(iteratorSameExpression); TEST_CASE(mismatchingContainerIterator); @@ -1869,6 +1870,22 @@ class TestStl : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void iterator30() + { + check("struct S {\n" // #12641 + " bool b;\n" + " std::list A, B;\n" + " void f();\n" + "};\n" + "void S::f() {\n" + " std::list::iterator i = (b ? B : A).begin();\n" + " while (i != (b ? B : A).end()) {\n" + " ++i;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void iteratorExpression() { check("std::vector& f();\n" "std::vector& g();\n"