libstdc++: Fix -Warray-bounds warning in std::vector::resize [PR114945]

This is yet another false positive warning fix. This time the compiler
can't prove that when the vector has sufficient excess capacity to
append new elements, the pointer to the existing storage is not null.

libstdc++-v3/ChangeLog:

	PR libstdc++/114945
	* include/bits/vector.tcc (vector::_M_default_append): Add
	unreachable condition so the compiler knows that _M_finish is
	not null.
	* testsuite/23_containers/vector/capacity/114945.cc: New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
This commit is contained in:
Jonathan Wakely 2025-03-31 12:30:44 +01:00 committed by Jonathan Wakely
parent 2fd74c7905
commit 844eed3364
No known key found for this signature in database
2 changed files with 39 additions and 0 deletions

View file

@ -768,6 +768,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (__navail >= __n)
{
if (!this->_M_impl._M_finish)
__builtin_unreachable();
_GLIBCXX_ASAN_ANNOTATE_GROW(__n);
this->_M_impl._M_finish =
std::__uninitialized_default_n_a(this->_M_impl._M_finish,

View file

@ -0,0 +1,36 @@
// { dg-options "-O2 -Werror=stringop-overflow -Werror=array-bounds" }
// { dg-do compile { target c++11 } }
// Bug libstdc++/114945
// Sporadic std::vector::resize() -Wstringop-overflow or -Warray-bounds warning
#include <stdint.h>
#include <vector>
template <typename a> struct b {
void resize(std::size_t c) { d.resize(c); }
template <typename e> void f(a, e);
std::vector<char> d;
};
#include <regex>
std::regex g;
uint64_t h;
uint32_t i;
struct s {
enum class j : size_t;
void k();
using l = b<j>;
std::vector<l> m;
};
enum class s::j : size_t { n };
void o() { g = ""; }
void s::k() {
l p;
auto q = uint32_t(), r = uint32_t();
if (h)
r = i;
b<size_t> t;
if (q || r)
p.f(j::n, 5);
t.resize(4);
m.push_back(p);
}