https://gcc.gnu.org/g:a5f7850221f935b97980e2a52b1aaeb944d7d1cf

commit r13-9488-ga5f7850221f935b97980e2a52b1aaeb944d7d1cf
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Fri Mar 28 15:41:41 2025 +0000

    libstdc++: Fix -Warray-bounds warning in std::vector<bool> [PR110498]
    
    In this case, we need to tell the compiler that the current size is not
    larger than the new size so that all the existing elements can be copied
    to the new storage. This avoids bogus warnings about overflowing the new
    storage when the compiler can't tell that that cannot happen.
    
    We might as well also hoist the loads of begin() and end() before the
    allocation too. All callers will have loaded at least begin() before
    calling _M_reallocate.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/110498
            * include/bits/vector.tcc (vector<bool, A>::_M_reallocate):
            Hoist loads of begin() and end() before allocation and use them
            to state an unreachable condition.
            * testsuite/23_containers/vector/bool/capacity/110498.cc: New
            test.
    
    Reviewed-by: Tomasz KamiƄski <tkami...@redhat.com>
    
    (cherry picked from commit aa3aaf2bfb8fcc17076993df4297597b68bc5f60)

Diff:
---
 libstdc++-v3/include/bits/vector.tcc                   |  5 ++++-
 .../23_containers/vector/bool/capacity/110498.cc       | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/vector.tcc 
b/libstdc++-v3/include/bits/vector.tcc
index 16ccfc7c02ea..58269cefeddf 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -848,9 +848,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     vector<bool, _Alloc>::
     _M_reallocate(size_type __n)
     {
+      const iterator __begin = begin(), __end = end();
+      if (size_type(__end - __begin) > __n)
+       __builtin_unreachable();
       _Bit_pointer __q = this->_M_allocate(__n);
       iterator __start(std::__addressof(*__q), 0);
-      iterator __finish(_M_copy_aligned(begin(), end(), __start));
+      iterator __finish(_M_copy_aligned(__begin, __end, __start));
       this->_M_deallocate();
       this->_M_impl._M_start = __start;
       this->_M_impl._M_finish = __finish;
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc 
b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc
new file mode 100644
index 000000000000..d2d09e10d19a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc
@@ -0,0 +1,18 @@
+// { dg-options "-O3 -Werror=array-bounds" }
+// { dg-do compile }
+
+// Bug libstdc++/110498
+// Spurious warnings stringop-overflow and array-bounds copying data as bytes
+// into vector::reserve
+
+#include <vector>
+
+void f(std::vector<bool>& v)
+{
+  // Warning emitted when set to any number in the range [1,64].
+  const std::size_t reserve_size = 30;
+
+  v.reserve(reserve_size);
+  v.push_back(0);
+}
+

Reply via email to