[committed] libstdc++: Make std::vector<bool> constructor noexcept (LWG 3778)

Message ID 20241203103258.261676-1-jwakely@redhat.com
State Committed
Commit d1318ebb7d1fb474a3b096406bda759187c56610
Headers
Series [committed] libstdc++: Make std::vector<bool> constructor noexcept (LWG 3778) |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Jonathan Wakely Dec. 3, 2024, 10:32 a.m. UTC
  LWG 3778 was approved in November 2022. We already implement all the
changes except for one, which this commit does.

The new test verifies all the changes from LWG 3778, not just the one
implemented here.

libstdc++-v3/ChangeLog:

	* include/bits/stl_bvector.h (vector(const allocator_type&)):
	Add noexcept, as per LWG 3778.
	* testsuite/23_containers/vector/bool/cons/lwg3778.cc: New test.
---

Tested x86_64-linux. Pushed to trunk.

 libstdc++-v3/include/bits/stl_bvector.h       |  2 +-
 .../23_containers/vector/bool/cons/lwg3778.cc | 87 +++++++++++++++++++
 2 files changed, 88 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/cons/lwg3778.cc
  

Patch

diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index 39d19e7954d..341eee33b21 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -787,7 +787,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       _GLIBCXX20_CONSTEXPR
       explicit
-      vector(const allocator_type& __a)
+      vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT
       : _Base(__a) { }
 
 #if __cplusplus >= 201103L
diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/cons/lwg3778.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/cons/lwg3778.cc
new file mode 100644
index 00000000000..49c510dd626
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/cons/lwg3778.cc
@@ -0,0 +1,87 @@ 
+// { dg-do compile { target c++11 } }
+
+// LWG 3778. vector<bool> missing exception specifications
+
+#include <vector>
+#include <testsuite_allocator.h>
+
+using V = std::vector<bool>;
+
+static_assert(std::is_nothrow_default_constructible<V>::value,
+	      "nothrow default constructible with std::allocator");
+static_assert(std::is_nothrow_constructible<V, V::allocator_type>::value,
+	      "nothrow constructible with allocator argument");
+static_assert(std::is_nothrow_move_constructible<V>::value,
+	      "unconditionally nothrow move constructible");
+static_assert(std::is_nothrow_move_assignable<V>::value,
+	      "nothrow move assignment with std::allocator");
+static_assert(std::__is_nothrow_swappable<V>::value,
+	      "nothrow swap with std::allocator");
+
+template<typename T>
+struct Allocator : __gnu_test::SimpleAllocator<T>
+{
+  Allocator() noexcept(false) { }
+
+  template<typename U>
+    Allocator(const Allocator<U>&) { }
+};
+
+using V2 = std::vector<bool, Allocator<bool>>;
+static_assert(std::is_default_constructible<V2>::value,
+	      "default constructible with Allocator<bool>");
+static_assert(std::is_nothrow_constructible<V2, V2::allocator_type>::value,
+	      "nothrow constructible with allocator argument");
+static_assert(! std::is_nothrow_default_constructible<V2>::value,
+	      "but not nothrow default constructible with Allocator<bool>");
+static_assert(std::is_nothrow_move_constructible<V2>::value,
+	      "also checked by ./noexcept_move_construct.cc");
+static_assert(std::__is_nothrow_swappable<V>::value,
+	      "nothrow swap with std::allocator");
+
+template<typename T, typename IAE, typename POCMA = IAE>
+struct PropAllocator : __gnu_test::SimpleAllocator<T>
+{
+  PropAllocator() noexcept { }
+
+  template<typename U>
+    PropAllocator(const PropAllocator<U, IAE, POCMA>&) { }
+
+  using is_always_equal = POCMA;
+  using propagate_on_container_move_assignment = IAE;
+};
+
+using V3 = std::vector<bool, PropAllocator<bool, std::false_type>>;
+static_assert(std::is_nothrow_move_constructible<V3>::value,
+	      "unconditionally nothrow move constructible");
+static_assert(std::is_nothrow_constructible<V3, V3::allocator_type>::value,
+	      "nothrow constructible with allocator argument");
+static_assert(! std::is_nothrow_move_assignable<V3>::value,
+	      "throwing move assignment with !(propagating || equal) alloc");
+#ifdef _GLIBCXX_RELEASE
+// We strengthen std::vector<bool, A>::swap to be always noexcept.
+static_assert(std::__is_nothrow_swappable<V3>::value,
+	      "nothrow swap even with !(propagating || equal) alloc");
+#endif
+
+using V4
+  = std::vector<bool, PropAllocator<bool, std::false_type, std::true_type>>;
+static_assert(std::is_nothrow_constructible<V4, V4::allocator_type>::value,
+	      "nothrow constructible with allocator argument");
+static_assert(std::is_nothrow_move_constructible<V4>::value,
+	      "unconditionally nothrow move constructible");
+static_assert(std::is_nothrow_move_assignable<V4>::value,
+	      "nothrow move assignment with propagating alloc");
+static_assert(std::__is_nothrow_swappable<V4>::value,
+	      "nothrow swap with always-equal alloc");
+
+using V5
+  = std::vector<bool, PropAllocator<bool, std::true_type, std::false_type>>;
+static_assert(std::is_nothrow_constructible<V5, V5::allocator_type>::value,
+	      "nothrow constructible with allocator argument");
+static_assert(std::is_nothrow_move_constructible<V5>::value,
+	      "unconditionally nothrow move constructible");
+static_assert(std::is_nothrow_move_assignable<V5>::value,
+	      "nothrow move assignment with always-equal alloc");
+static_assert(std::__is_nothrow_swappable<V5>::value,
+	      "nothrow swap with always-equal alloc");