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.
---

Tested x86_64-linux.

 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 7a92f34ec64..66d73b4cfd7 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 00000000000..daafc59d5a9
--- /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 <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);
+}
-- 
2.49.0

Reply via email to