re PR libstdc++/66078 (20_util/specialized_algorithms/uninitialized_copy/808590.cc...
authorJonathan Wakely <jwakely@redhat.com>
Wed, 20 May 2015 17:11:03 +0000 (18:11 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 20 May 2015 17:11:03 +0000 (18:11 +0100)
PR libstdc++/66078
* include/bits/stl_iterator.h (__make_move_if_noexcept_iterator): Add
overload for pointers.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/
808590.cc: Add -std=gnu++03 switch.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/
808590-cxx11.cc: Copy of 808590.cc to test with -std=gnu++11.
* testsuite/23_containers/vector/modifiers/push_back/
strong_guarantee.cc: New.

From-SVN: r223449

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_iterator.h
libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/808590-cxx11.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/808590.cc
libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/strong_guarantee.cc [new file with mode: 0644]

index 6c5964af75ad88cdb6c4d89d330642424c3fc9c1..50b1626cfb84fe6c412da71ada3260f3826b8e68 100644 (file)
@@ -1,3 +1,15 @@
+2015-05-20  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/66078
+       * include/bits/stl_iterator.h (__make_move_if_noexcept_iterator): Add
+       overload for pointers.
+       * testsuite/20_util/specialized_algorithms/uninitialized_copy/
+       808590.cc: Add -std=gnu++03 switch.
+       * testsuite/20_util/specialized_algorithms/uninitialized_copy/
+       808590-cxx11.cc: Copy of 808590.cc to test with -std=gnu++11.
+       * testsuite/23_containers/vector/modifiers/push_back/
+       strong_guarantee.cc: New.
+
 2015-05-19  Jonathan Wakely  <jwakely@redhat.com>
 
        * include/bits/stl_list.h (_M_resize_pos(size_type&)): Declare.
index d4ea6577a4986ed0c3597bd83ab8a095edd624b0..b8e79dfa7e4e0846540560eacb43f586e33df38e 100644 (file)
@@ -1194,6 +1194,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __make_move_if_noexcept_iterator(_Iterator __i)
     { return _ReturnType(__i); }
 
+  // Overload for pointers that matches std::move_if_noexcept more closely,
+  // returning a constant iterator when we don't want to move.
+  template<typename _Tp, typename _ReturnType
+    = typename conditional<__move_if_noexcept_cond<_Tp>::value,
+                          const _Tp*, move_iterator<_Tp*>>::type>
+    inline _ReturnType
+    __make_move_if_noexcept_iterator(_Tp* __i)
+    { return _ReturnType(__i); }
+
   // @} group iterators
 
   template<typename _Iterator>
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/808590-cxx11.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/808590-cxx11.cc
new file mode 100644 (file)
index 0000000..9597a7b
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2012-2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11" }
+
+// This is identical to ./808590.cc but using -std=gnu++11
+// See https://gcc.gnu.org/ml/libstdc++/2014-05/msg00027.html
+
+#include <vector>
+#include <stdexcept>
+
+// 4.4.x only
+struct c
+{
+  void *m;
+
+  c(void* o = 0) : m(o) {}
+  c(const c &r) : m(r.m) {}
+
+  template<class T>
+    explicit c(T &o) : m((void*)0xdeadbeef) { }
+};
+
+int main()
+{
+  std::vector<c> cbs;
+  const c cb((void*)0xcafebabe);
+
+  for (int fd = 62; fd < 67; ++fd)
+    {
+      cbs.resize(fd + 1);
+      cbs[fd] = cb;
+    }
+
+  for (int fd = 62; fd< 67; ++fd)
+    if (cb.m != cbs[fd].m)
+      throw std::runtime_error("wrong");
+  return 0;
+}
index 53b2d6d317624e17d7b79261c08ebdb1295fed70..7d20f8541a9c2f9f93e51d99077d640d0a856158 100644 (file)
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+// { dg-options "-std=gnu++03" }
+
 #include <vector>
 #include <stdexcept>
 
 // 4.4.x only
-struct c 
+struct c
 {
   void *m;
 
@@ -30,12 +32,12 @@ struct c
     explicit c(T &o) : m((void*)0xdeadbeef) { }
 };
 
-int main() 
+int main()
 {
   std::vector<c> cbs;
   const c cb((void*)0xcafebabe);
 
-  for (int fd = 62; fd < 67; ++fd) 
+  for (int fd = 62; fd < 67; ++fd)
     {
       cbs.resize(fd + 1);
       cbs[fd] = cb;
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/strong_guarantee.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/strong_guarantee.cc
new file mode 100644 (file)
index 0000000..461f6ea
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <vector>
+#include <testsuite_hooks.h>
+
+template<typename T>
+void check(const T& t)
+{
+  for (auto& e : t)
+    VERIFY( !e.moved_from);
+}
+
+// This type is CopyInsertable into std::vector<Bomb> so push_back should
+// have the strong exception-safety guarantee.
+struct Bomb
+{
+  Bomb() = default;
+
+  Bomb(const Bomb& b)
+  : armed(b.armed)
+  {
+    tick();
+  }
+
+  Bomb(Bomb&& b) noexcept(false)
+  : armed(b.armed)
+  {
+    tick();
+    b.moved_from = true;
+  }
+
+  // std::vector in GCC 4.x tries to use this constructor
+  template<typename T> Bomb(T&) = delete;
+
+  bool moved_from = false;
+  bool armed = true;
+
+private:
+  void tick()
+  {
+    if (armed && ticks++)
+      throw 1;
+  }
+
+  static int ticks;
+};
+
+int Bomb::ticks = 0;
+
+void test01()
+{
+  std::vector<Bomb> v(2); // fill with armed bombs
+  v.resize(v.capacity()); // ensure no unused capacity
+  check(v);               // sanity check
+
+  try {
+    Bomb defused;
+    // don't want any copies/moves of this object to throw
+    defused.armed = false;
+    // insert new element, existing elements will be relocated and explode
+    v.push_back(defused);
+    VERIFY(false); // should be unreachable
+  } catch (int) {
+    check(v);  // make sure no elements have been moved from
+  }
+}
+
+int main()
+{
+  test01();
+}