Fix #13327 FN mismatchingContainers for struct member and c_str()#7024
Fix #13327 FN mismatchingContainers for struct member and c_str()#7024chrchr-github merged 6 commits intodanmar:mainfrom
Conversation
lib/checkstl.cpp
Outdated
| } | ||
| if (values.size() == 1) | ||
| return values.front(); | ||
| it = std::find_if(values.cbegin(), values.cend(), [](const ValueFlow::Value& v) { |
There was a problem hiding this comment.
This is problematic if there is divergent lifetimes, that is why we check the size is 1 or no duplicates for iterator kinds. Why is there multiple lifetimes? Do we have a lifetime for t.s.a and a both?
There was a problem hiding this comment.
This is problematic if there is divergent lifetimes, that is why we check the size is 1 or no duplicates for iterator kinds. Why is there multiple lifetimes? Do we have a lifetime for
t.s.aandaboth?
In the s.a example, the lifetime tokvalues are s and .. But I think it makes sense to choose the dot, unless there can be multiple dots.
There was a problem hiding this comment.
Its the . in s.a I assume? Ideally we should remove the lifetimes that refer to a sub expression of another lifetime from the vector. Something like this function could be called here(its not tested though):
std::vector<ValueFlow::Value> pruneLifetimes(std::vector<ValueFlow::Value> lifetimes)
{
std::vector<ValueFlow::Value> result;
auto start = lifetimes.begin();
while(start != lifetimes.end())
{
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) or astHasToken(tok2, tok1);
});
auto root = std::min_element(start, it, [](const ValueFlow::Value& x, const ValueFlow::Value& y) {
return astHasToken(x.tokvalue, y.tokvalue);
});
result.push_back(*root);
start = it;
}
return result;
}There was a problem hiding this comment.
Not entirely sure what it does, but it seems to work 👍
There was a problem hiding this comment.
First it groups the lifetimes together using std::partition with the lifetimes that refer to the same token or token of a subexpression. Then it finds the lifetime in that group that refers to the "highest" parent using std::min_element and adds that to the vector. Hopefully that makes sense.
Co-authored-by: Paul Fultz II pfultz2@yahoo.com