Skip to content

Commit 02063b6

Browse files
authored
Fix 13408: FP mismatchingContainers when taking address of dereferenced iterator (#7092)
1 parent 719ee61 commit 02063b6

3 files changed

Lines changed: 15 additions & 3 deletions

File tree

lib/checkstl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ static std::vector<ValueFlow::Value> pruneLifetimes(std::vector<ValueFlow::Value
736736
const Token* tok1 = start->tokvalue;
737737
auto it = std::partition(start, lifetimes.end(), [&](const ValueFlow::Value& v) {
738738
const Token* tok2 = v.tokvalue;
739-
return astHasToken(tok1, tok2) || astHasToken(tok2, tok1);
739+
return start->lifetimeKind == v.lifetimeKind && (astHasToken(tok1, tok2) || astHasToken(tok2, tok1));
740740
});
741741
auto root = std::min_element(start, it, [](const ValueFlow::Value& x, const ValueFlow::Value& y) {
742742
return x.tokvalue != y.tokvalue && astHasToken(x.tokvalue, y.tokvalue);

lib/valueflow.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,7 +1519,9 @@ static std::vector<ValueFlow::LifetimeToken> getLifetimeTokens(const Token* tok,
15191519
return {{tok, true, std::move(errorPath)}};
15201520
const Token* contok = var->nameToken()->astParent()->astOperand2();
15211521
if (astIsContainer(contok))
1522-
return getLifetimeTokens(contok, escape, std::move(errorPath), pred, settings, depth - 1);
1522+
return ValueFlow::LifetimeToken::setAddressOf(
1523+
getLifetimeTokens(contok, escape, std::move(errorPath), pred, settings, depth - 1),
1524+
false);
15231525
return std::vector<ValueFlow::LifetimeToken>{};
15241526
} else {
15251527
return std::vector<ValueFlow::LifetimeToken> {};
@@ -1607,7 +1609,9 @@ static std::vector<ValueFlow::LifetimeToken> getLifetimeTokens(const Token* tok,
16071609
if (v.tokvalue == tok)
16081610
continue;
16091611
errorPath.insert(errorPath.end(), v.errorPath.cbegin(), v.errorPath.cend());
1610-
return getLifetimeTokens(v.tokvalue, escape, std::move(errorPath), pred, settings, depth - 1);
1612+
return ValueFlow::LifetimeToken::setAddressOf(
1613+
getLifetimeTokens(v.tokvalue, escape, std::move(errorPath), pred, settings, depth - 1),
1614+
false);
16111615
}
16121616
} else {
16131617
return ValueFlow::LifetimeToken::setAddressOf(getLifetimeTokens(vartok, escape, std::move(errorPath), pred, settings, depth - 1),

test/teststl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,6 +2263,14 @@ class TestStl : public TestFixture {
22632263
" v.erase(v.begin(), v.end());\n"
22642264
"}\n");
22652265
ASSERT_EQUALS("", errout_str());
2266+
2267+
// #13408
2268+
check("void f(const std::vector<int>& v) {\n"
2269+
" for (const auto& i : v) {\n"
2270+
" if (std::distance(&*v.cbegin(), &i)) {}\n"
2271+
" } \n"
2272+
"}\n");
2273+
ASSERT_EQUALS("", errout_str());
22662274
}
22672275

22682276
void eraseIteratorOutOfBounds() {

0 commit comments

Comments
 (0)