]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Fix -Warray-bounds warning in std::vector::resize [PR114945]
authorJonathan Wakely <jwakely@redhat.com>
Mon, 31 Mar 2025 11:30:44 +0000 (12:30 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 2 Apr 2025 08:55:45 +0000 (09:55 +0100)
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>
(cherry picked from commit 844eed3364309bd20cbb7d6793a16b7c6b889ba4)

libstdc++-v3/include/bits/vector.tcc
libstdc++-v3/testsuite/23_containers/vector/capacity/114945.cc [new file with mode: 0644]

index 0458d560075ff5e624ec4947d9a47b96c89c6796..0bd1ae411028dd6e3a99dfe4c3a4ac521e22c692 100644 (file)
@@ -816,6 +816,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 (file)
index 0000000..daafc59
--- /dev/null
@@ -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);
+}