aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2025-03-28 15:41:41 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2025-03-31 22:54:08 +0100
commitaa3aaf2bfb8fcc17076993df4297597b68bc5f60 (patch)
tree086cdf4d8b43a4605a9bc0d5e99464f30d1ce895
parent1f6c19f307c8de9830130a0ba071c24e3835beb3 (diff)
downloadgcc-aa3aaf2bfb8fcc17076993df4297597b68bc5f60.zip
gcc-aa3aaf2bfb8fcc17076993df4297597b68bc5f60.tar.gz
gcc-aa3aaf2bfb8fcc17076993df4297597b68bc5f60.tar.bz2
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 <tkaminsk@redhat.com>
-rw-r--r--libstdc++-v3/include/bits/vector.tcc5
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc18
2 files changed, 22 insertions, 1 deletions
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index 29aa63e..7a92f34 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -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
index 0000000..f848edc
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/110498.cc
@@ -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);
+}
+