]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Fix -Warray-bounds warning in std::vector<bool> [PR110498]
authorJonathan Wakely <jwakely@redhat.com>
Fri, 28 Mar 2025 15:41:41 +0000 (15:41 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 31 Mar 2025 21:54:08 +0000 (22:54 +0100)
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 <tkaminsk@redhat.com>
libstdc++-v3/include/bits/vector.tcc
libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc [new file with mode: 0644]

index 29aa63e47428d78b06d38f936e104328e3826d6d..7a92f34ec644b9dc35a31bc3f6f5ff0deea2c4e3 100644 (file)
@@ -1106,9 +1106,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 (file)
index 0000000..f848edc
--- /dev/null
@@ -0,0 +1,18 @@
+// { dg-options "-O3 -Werror=array-bounds -fno-assume-sane-operators-new-delete" }
+// { 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);
+}
+