Fix #11553 pop_back on empty container is UB#4789
Fix #11553 pop_back on empty container is UB#4789firewave merged 13 commits intocppcheck-opensource:mainfrom
Conversation
| !containerAppendsElement(container, parent)))) { | ||
| if (value.intvalue == 0 && (indexTok || | ||
| (containerYieldsElement(container, parent) && !containerAppendsElement(container, parent)) || | ||
| (value.isKnown() && containerPopsElement(container, parent)))) { |
There was a problem hiding this comment.
We should be able to warn when the value is not known as well.
There was a problem hiding this comment.
The problem is code like
void f(std::vector<int>& v) {
v.pop_back();
if (v.empty()) {}
}
We don't seem to take into account that the size changes with pop_back().
There was a problem hiding this comment.
That looks like a bug in Valueflow. Maybe we don't account for the POP action.
There was a problem hiding this comment.
It's not necessarily a ValueFlow issue.
Propagating possible values to locations preceding a size-changing action seems wrong.
We don't warn for this either, although v.resize() does get a possible empty value:
void g(std::vector<int>& v) {
int n = v.size();
v.resize(n - 1);
if (v.empty()) {}
}
containerYieldsElement() is obviously false, and containerAppendsElement() does not check whether resize() adds or removes elements.
There was a problem hiding this comment.
We also don't warn for
void g(std::vector<int>& v) {
v.push_back(1);
if (v.empty()) {}
}
There was a problem hiding this comment.
Nice. So we should be able to warn for
void f(std::vector<int>& v) {
if (v.empty()) {}
v.pop_back();
}
after those PRs have been merged.
The resize(n - 1) example is equivalent to the pop_back() one in the 2nd comment above, so we shouldn't warn for those.
12e8aae to
42ffe02
Compare
No description provided.