From 844eed3364309bd20cbb7d6793a16b7c6b889ba4 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 31 Mar 2025 12:30:44 +0100 Subject: [PATCH] libstdc++: Fix -Warray-bounds warning in std::vector::resize [PR114945] MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- libstdc++-v3/include/bits/vector.tcc | 3 ++ .../23_containers/vector/capacity/114945.cc | 36 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 libstdc++-v3/testsuite/23_containers/vector/capacity/114945.cc diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 7a92f34ec644..66d73b4cfd7e 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -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, diff --git a/libstdc++-v3/testsuite/23_containers/vector/capacity/114945.cc b/libstdc++-v3/testsuite/23_containers/vector/capacity/114945.cc new file mode 100644 index 000000000000..daafc59d5a9d --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/capacity/114945.cc @@ -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 +#include +template struct b { + void resize(std::size_t c) { d.resize(c); } + template void f(a, e); + std::vector d; +}; +#include +std::regex g; +uint64_t h; +uint32_t i; +struct s { + enum class j : size_t; + void k(); + using l = b; + std::vector 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 t; + if (q || r) + p.f(j::n, 5); + t.resize(4); + m.push_back(p); +} -- 2.47.2