Skip to content

Commit

Permalink
Fix 13408: FP mismatchingContainers when taking address of dereferenc…
Browse files Browse the repository at this point in the history
…ed iterator (#7092)
  • Loading branch information
pfultz2 authored Dec 10, 2024
1 parent 719ee61 commit 02063b6
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 3 deletions.
2 changes: 1 addition & 1 deletion lib/checkstl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ static std::vector<ValueFlow::Value> pruneLifetimes(std::vector<ValueFlow::Value
const Token* tok1 = start->tokvalue;
auto it = std::partition(start, lifetimes.end(), [&](const ValueFlow::Value& v) {
const Token* tok2 = v.tokvalue;
return astHasToken(tok1, tok2) || astHasToken(tok2, tok1);
return start->lifetimeKind == v.lifetimeKind && (astHasToken(tok1, tok2) || astHasToken(tok2, tok1));
});
auto root = std::min_element(start, it, [](const ValueFlow::Value& x, const ValueFlow::Value& y) {
return x.tokvalue != y.tokvalue && astHasToken(x.tokvalue, y.tokvalue);
Expand Down
8 changes: 6 additions & 2 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1519,7 +1519,9 @@ static std::vector<ValueFlow::LifetimeToken> getLifetimeTokens(const Token* tok,
return {{tok, true, std::move(errorPath)}};
const Token* contok = var->nameToken()->astParent()->astOperand2();
if (astIsContainer(contok))
return getLifetimeTokens(contok, escape, std::move(errorPath), pred, settings, depth - 1);
return ValueFlow::LifetimeToken::setAddressOf(
getLifetimeTokens(contok, escape, std::move(errorPath), pred, settings, depth - 1),
false);
return std::vector<ValueFlow::LifetimeToken>{};
} else {
return std::vector<ValueFlow::LifetimeToken> {};
Expand Down Expand Up @@ -1607,7 +1609,9 @@ static std::vector<ValueFlow::LifetimeToken> getLifetimeTokens(const Token* tok,
if (v.tokvalue == tok)
continue;
errorPath.insert(errorPath.end(), v.errorPath.cbegin(), v.errorPath.cend());
return getLifetimeTokens(v.tokvalue, escape, std::move(errorPath), pred, settings, depth - 1);
return ValueFlow::LifetimeToken::setAddressOf(
getLifetimeTokens(v.tokvalue, escape, std::move(errorPath), pred, settings, depth - 1),
false);
}
} else {
return ValueFlow::LifetimeToken::setAddressOf(getLifetimeTokens(vartok, escape, std::move(errorPath), pred, settings, depth - 1),
Expand Down
8 changes: 8 additions & 0 deletions test/teststl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2263,6 +2263,14 @@ class TestStl : public TestFixture {
" v.erase(v.begin(), v.end());\n"
"}\n");
ASSERT_EQUALS("", errout_str());

// #13408
check("void f(const std::vector<int>& v) {\n"
" for (const auto& i : v) {\n"
" if (std::distance(&*v.cbegin(), &i)) {}\n"
" } \n"
"}\n");
ASSERT_EQUALS("", errout_str());
}

void eraseIteratorOutOfBounds() {
Expand Down

0 comments on commit 02063b6

Please sign in to comment.