Skip to content

Commit 94f28a2

Browse files
Fix #12641 FP mismatchingContainers with repeated ternary (#6337)
1 parent f7949e7 commit 94f28a2

2 files changed

Lines changed: 28 additions & 5 deletions

File tree

lib/checkstl.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -727,12 +727,18 @@ static bool isSameIteratorContainerExpression(const Token* tok1,
727727

728728
static ValueFlow::Value getLifetimeIteratorValue(const Token* tok, MathLib::bigint path = 0)
729729
{
730+
auto findIterVal = [](const std::vector<ValueFlow::Value>& values, const std::vector<ValueFlow::Value>::const_iterator beg) {
731+
return std::find_if(beg, values.cend(), [](const ValueFlow::Value& v) {
732+
return v.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator;
733+
});
734+
};
730735
std::vector<ValueFlow::Value> values = ValueFlow::getLifetimeObjValues(tok, false, path);
731-
auto it = std::find_if(values.cbegin(), values.cend(), [](const ValueFlow::Value& v) {
732-
return v.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator;
733-
});
734-
if (it != values.end())
735-
return *it;
736+
auto it = findIterVal(values, values.begin());
737+
if (it != values.end()) {
738+
auto it2 = findIterVal(values, it + 1);
739+
if (it2 == values.cend())
740+
return *it;
741+
}
736742
if (values.size() == 1)
737743
return values.front();
738744
return ValueFlow::Value{};

test/teststl.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class TestStl : public TestFixture {
6969
TEST_CASE(iterator27); // #10378
7070
TEST_CASE(iterator28); // #10450
7171
TEST_CASE(iterator29);
72+
TEST_CASE(iterator30);
7273
TEST_CASE(iteratorExpression);
7374
TEST_CASE(iteratorSameExpression);
7475
TEST_CASE(mismatchingContainerIterator);
@@ -1869,6 +1870,22 @@ class TestStl : public TestFixture {
18691870
ASSERT_EQUALS("", errout_str());
18701871
}
18711872

1873+
void iterator30()
1874+
{
1875+
check("struct S {\n" // #12641
1876+
" bool b;\n"
1877+
" std::list<int> A, B;\n"
1878+
" void f();\n"
1879+
"};\n"
1880+
"void S::f() {\n"
1881+
" std::list<int>::iterator i = (b ? B : A).begin();\n"
1882+
" while (i != (b ? B : A).end()) {\n"
1883+
" ++i;\n"
1884+
" }\n"
1885+
"}\n");
1886+
ASSERT_EQUALS("", errout_str());
1887+
}
1888+
18721889
void iteratorExpression() {
18731890
check("std::vector<int>& f();\n"
18741891
"std::vector<int>& g();\n"

0 commit comments

Comments
 (0)