[libcxx-commits] [libcxx] [libc++] Validate exception throwing for vector mutators on max_size violation (PR #131953)

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jun 20 18:18:31 PDT 2025


https://github.com/winner245 updated https://github.com/llvm/llvm-project/pull/131953

>From 679d36c3e77b33d3b7f9026a87d5d4b6a7872851 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Tue, 18 Mar 2025 22:01:01 -0400
Subject: [PATCH 1/2] Validate exception throwing for vector mutators on
 max_size violation

---
 .../vector.bool/append_range.pass.cpp         |   3 -
 .../append_range_exceptions.pass.cpp          |  59 ++++++++++
 .../emplace_back_exceptions.pass.cpp          |  36 ++++++
 .../vector.bool/emplace_exceptions.pass.cpp   |  65 +++++++++++
 .../vector.bool/insert_exceptions.pass.cpp    | 108 ++++++++++++++++++
 .../vector.bool/insert_range.pass.cpp         |   3 -
 .../insert_range_exceptions.pass.cpp          |  72 ++++++++++++
 .../vector.bool/push_back_exceptions.pass.cpp |  34 ++++++
 .../sequences/vector.bool/reserve.pass.cpp    |  18 ---
 .../vector.bool/reserve_exceptions.pass.cpp   |  68 +++++++++++
 .../resize_size_exceptions.pass.cpp           |  68 +++++++++++
 .../resize_size_value_exceptions.pass.cpp     |  71 ++++++++++++
 .../reserve_exceptions.pass.cpp               |  13 ++-
 .../resize_size_exceptions.pass.cpp           |  16 ++-
 .../resize_size_value_exceptions.pass.cpp     |  10 +-
 .../shrink_to_fit_exceptions.pass.cpp         |   4 +
 .../vector.modifiers/append_range.pass.cpp    |   3 -
 .../append_range_exceptions.pass.cpp          |  45 ++++++++
 .../emplace_back_exception_safety.pass.cpp    |  34 ++++++
 .../emplace_exceptions.pass.cpp               |  61 ++++++++++
 .../insert_exceptions.pass.cpp                | 101 ++++++++++++++++
 .../vector.modifiers/insert_range.pass.cpp    |   3 -
 .../insert_range_exceptions.pass.cpp          |  69 +++++++++++
 .../push_back_exception_safety.pass.cpp       |  15 ++-
 24 files changed, 939 insertions(+), 40 deletions(-)
 create mode 100644 libcxx/test/std/containers/sequences/vector.bool/append_range_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector.bool/emplace_back_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector.bool/emplace_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector.bool/insert_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector.bool/insert_range_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector.bool/push_back_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector.bool/reserve_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector.bool/resize_size_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector.bool/resize_size_value_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back_exception_safety.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_exceptions.pass.cpp
 create mode 100644 libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range_exceptions.pass.cpp

diff --git a/libcxx/test/std/containers/sequences/vector.bool/append_range.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/append_range.pass.cpp
index 84047ea15c6cf..8dea772375490 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/append_range.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/append_range.pass.cpp
@@ -65,8 +65,5 @@ int main(int, char**) {
   test();
   static_assert(test());
 
-  // Note: `test_append_range_exception_safety_throwing_copy` doesn't apply because copying booleans cannot throw.
-  test_append_range_exception_safety_throwing_allocator<std::vector, bool>();
-
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector.bool/append_range_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/append_range_exceptions.pass.cpp
new file mode 100644
index 0000000000000..63f23926f5f0e
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/append_range_exceptions.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+// vector<bool>
+
+// template<container-compatible-range<bool> R>
+//   constexpr void append_range(R&& rg); // C++23
+
+#include <cassert>
+#include <vector>
+
+#include "../insert_range_sequence_containers.h"
+#include "test_allocator.h"
+
+void test() {
+  // Note: `test_append_range_exception_safety_throwing_copy` doesn't apply because copying booleans cannot throw.
+  test_append_range_exception_safety_throwing_allocator<std::vector, bool>();
+
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size() - 2, true);
+    bool a[] = {false, true, false};
+    try {
+      v.append_range(a);
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.size() == v.max_size() - 2);
+      for (std::size_t i = 0; i < v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+  {
+    std::vector<bool, limited_allocator<bool, 10> > v(10, true);
+    bool a[10 * 65536] = {};
+    try {
+      v.append_range(a);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == 10);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+}
+
+int main(int, char**) {
+  test();
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/emplace_back_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/emplace_back_exceptions.pass.cpp
new file mode 100644
index 0000000000000..fb8504b60acd9
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/emplace_back_exceptions.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+// vector<bool>
+
+// template <class... Args>
+//     reference emplace_back(Args&&... args); // reference in C++17
+
+#include <cassert>
+#include <vector>
+
+#include "test_allocator.h"
+
+int main(int, char**) {
+  using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+  Vec v(Vec().max_size(), true);
+  try {
+    v.emplace_back(true);
+    assert(false);
+  } catch (...) {
+    assert(v.size() == v.max_size());
+    for (std::size_t i = 0; i != v.size(); ++i)
+      assert(v[i] == true);
+  }
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/emplace_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/emplace_exceptions.pass.cpp
new file mode 100644
index 0000000000000..5daea125fc555
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/emplace_exceptions.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+// vector<bool>
+
+// template <class... Args> iterator emplace(const_iterator pos, Args&&... args);
+
+#include <cassert>
+#include <vector>
+
+#include "test_allocator.h"
+
+void test() {
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size(), true);
+    try {
+      v.emplace(v.begin(), true);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size(), true);
+    try {
+      v.emplace(v.end(), true);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size(), true);
+    try {
+      v.emplace(v.begin() + v.size() / 2, true);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+}
+
+int main(int, char**) {
+  test();
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/insert_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/insert_exceptions.pass.cpp
new file mode 100644
index 0000000000000..a9742ffe2a5a3
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/insert_exceptions.pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+// vector<bool>
+
+// iterator insert(const_iterator position, const value_type& x);
+// iterator insert(const_iterator position, size_type n, const value_type& x);
+// iterator insert(const_iterator p, initializer_list<value_type> il);
+// template <class Iter>
+//   iterator insert(const_iterator position, Iter first, Iter last);
+
+#include <cassert>
+#include <vector>
+
+#include "test_allocator.h"
+#include "test_macros.h"
+
+void test() {
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size(), true);
+    try {
+      v.insert(v.begin(), false);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size(), false);
+    try {
+      v.insert(v.end(), 0);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == false);
+    }
+  }
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size(), true);
+    try {
+      v.insert(v.begin() + v.size() / 2, false);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size(), true);
+    try {
+      v.insert(v.begin(), 1, false);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size() - 2, true);
+    bool a[] = {true, false, true};
+    try {
+      v.insert(v.begin() + v.size() / 2, std::begin(a), std::end(a));
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size() - 2);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+#if TEST_STD_VER >= 11
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size() - 2, true);
+    try {
+      v.insert(v.begin(), {true, false, true});
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size() - 2);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+#endif
+}
+
+int main(int, char**) {
+  test();
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/insert_range.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/insert_range.pass.cpp
index e9a84150feb82..486ffaf5ec56c 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/insert_range.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/insert_range.pass.cpp
@@ -84,9 +84,6 @@ int main(int, char**) {
   test();
   static_assert(test());
 
-  // Note: `test_insert_range_exception_safety_throwing_copy` doesn't apply because copying booleans cannot throw.
-  test_insert_range_exception_safety_throwing_allocator<std::vector, bool>();
-
 #ifndef TEST_HAS_NO_LOCALIZATION
   test_counted_istream_view();
 #endif
diff --git a/libcxx/test/std/containers/sequences/vector.bool/insert_range_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/insert_range_exceptions.pass.cpp
new file mode 100644
index 0000000000000..c521d91d26c1d
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/insert_range_exceptions.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+// vector<bool>
+
+// template<container-compatible-range<T> R>
+//   constexpr iterator insert_range(const_iterator position, R&& rg); // C++23
+
+#include <cassert>
+#include <vector>
+
+#include "../insert_range_sequence_containers.h"
+#include "test_allocator.h"
+
+void test() {
+  // Note: `test_insert_range_exception_safety_throwing_copy` doesn't apply because copying booleans cannot throw.
+  test_insert_range_exception_safety_throwing_allocator<std::vector, bool>();
+
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size() - 2, true);
+    bool a[] = {true, false, true};
+    try {
+      v.insert_range(v.end(), a);
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.size() == v.max_size() - 2);
+      for (std::size_t i = 0; i < v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size() - 2, false);
+    bool a[] = {true, false, true};
+    try {
+      v.insert_range(v.begin(), a);
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.size() == v.max_size() - 2);
+      for (std::size_t i = 0; i < v.size(); ++i)
+        assert(v[i] == false);
+    }
+  }
+  {
+    std::vector<bool, limited_allocator<bool, 10> > v(10, true);
+    bool a[10 * 65536] = {};
+    try {
+      v.insert_range(v.begin() + v.size() / 2, a);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == 10);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+}
+
+int main(int, char**) {
+  test();
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/push_back_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/push_back_exceptions.pass.cpp
new file mode 100644
index 0000000000000..272325bec1768
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/push_back_exceptions.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+// vector<bool>
+
+// void push_back(const value_type& x);
+
+#include <cassert>
+#include <vector>
+
+#include "test_allocator.h"
+
+int main(int, char**) {
+  using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+  Vec v(Vec().max_size(), true);
+  try {
+    v.push_back(true);
+    assert(false);
+  } catch (...) {
+    assert(v.size() == v.max_size());
+    for (std::size_t i = 0; i != v.size(); ++i)
+      assert(v[i] == true);
+  }
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/reserve.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/reserve.pass.cpp
index e0caeb0083fbb..ce51722d2a684 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/reserve.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/reserve.pass.cpp
@@ -13,7 +13,6 @@
 
 #include <vector>
 #include <cassert>
-#include <stdexcept>
 
 #include "test_macros.h"
 #include "min_allocator.h"
@@ -57,23 +56,6 @@ TEST_CONSTEXPR_CXX20 bool tests() {
     assert(v.capacity() >= 150);
   }
 #endif
-#ifndef TEST_HAS_NO_EXCEPTIONS
-  if (!TEST_IS_CONSTANT_EVALUATED) {
-    std::vector<bool, limited_allocator<bool, 10> > v;
-    v.reserve(5);
-    try {
-      // A typical implementation would allocate chunks of bits.
-      // In libc++ the chunk has the same size as the machine word. It is
-      // reasonable to assume that in practice no implementation would use
-      // 64 kB or larger chunks.
-      v.reserve(10 * 65536);
-      assert(false);
-    } catch (const std::length_error&) {
-      // no-op
-    }
-    assert(v.capacity() >= 5);
-  }
-#endif
 
   return true;
 }
diff --git a/libcxx/test/std/containers/sequences/vector.bool/reserve_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/reserve_exceptions.pass.cpp
new file mode 100644
index 0000000000000..8dc31251bc73a
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/reserve_exceptions.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+// vector<bool>
+
+// void reserve(size_type n);
+
+#include <cassert>
+#include <stdexcept>
+#include <vector>
+
+#include "test_allocator.h"
+
+void test() {
+  {
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.reserve(5);
+    try {
+      // A typical implementation would allocate chunks of bits.
+      // In libc++ the chunk has the same size as the machine word. It is
+      // reasonable to assume that in practice no implementation would use
+      // 64 kB or larger chunks.
+      v.reserve(10 * 65536);
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.empty());
+      assert(v.capacity() >= 5);
+    }
+  }
+  {
+    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
+    Vec v(Vec().max_size(), true);
+    try {
+      v.reserve(v.max_size() + 1);
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i < v.size(); ++i)
+        assert(v[i] == true);
+    }
+  }
+  {
+    bool a[] = {true, false, true, false, true};
+    std::vector<bool> v(std::begin(a), std::end(a));
+    try {
+      v.reserve(v.max_size() + 1);
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.size() == 5);
+      assert(v.capacity() >= 5);
+      for (std::size_t i = 0; i < v.size(); ++i)
+        assert(v[i] == a[i]);
+    }
+  }
+}
+
+int main(int, char**) {
+  test();
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/resize_size_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/resize_size_exceptions.pass.cpp
new file mode 100644
index 0000000000000..8a1539e40649c
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/resize_size_exceptions.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+// vector<bool>
+
+// void resize(size_type sz);
+
+#include <algorithm>
+#include <cassert>
+#include <stdexcept>
+#include <vector>
+
+#include "test_allocator.h"
+
+void test() {
+  {
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(5);
+    try {
+      // It is reasonable to assume that no vector<bool> implementation would use
+      // 64 kB or larger chunk size for the underlying bits storage.
+      v.resize(10 * 65536); // 10 * max_chunk_size
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.size() == 5);
+      assert(v.capacity() >= 5);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(!v[i]);
+    }
+  }
+  {
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size() / 2);
+    try {
+      v.resize(v.max_size() + 1);
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.size() == v.max_size() / 2);
+      for (std::size_t i = 0; i < v.size(); ++i)
+        assert(v[i] == false);
+    }
+  }
+  {
+    bool a[] = {true, false, true, false, true};
+    std::vector<bool> v(std::begin(a), std::end(a));
+    try {
+      v.resize(v.max_size() + 1);
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.size() == 5);
+      assert(v.capacity() >= 5);
+      assert(std::equal(v.begin(), v.end(), std::begin(a)));
+    }
+  }
+}
+
+int main(int, char**) {
+  test();
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/resize_size_value_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/resize_size_value_exceptions.pass.cpp
new file mode 100644
index 0000000000000..6af3c9ac8fa1a
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/resize_size_value_exceptions.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+
+// template<container-compatible-range<T> R>
+//   constexpr iterator insert_range(const_iterator position, R&& rg); // C++23
+
+#include <algorithm>
+#include <cassert>
+#include <stdexcept>
+#include <vector>
+
+#include "../insert_range_sequence_containers.h"
+#include "test_allocator.h"
+
+void test() {
+  {
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(5);
+    try {
+      // It is reasonable to assume that no vector<bool> implementation would use
+      // 64 kB or larger chunk size for the underlying bits storage.
+      v.resize(10 * 65536, true); // 10 * max_chunk_size
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.size() == 5);
+      assert(v.capacity() >= 5);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(!v[i]);
+    }
+  }
+  {
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size() / 2);
+    try {
+      v.resize(v.max_size() + 1, true);
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.size() == v.max_size() / 2);
+      for (std::size_t i = 0; i < v.size(); ++i)
+        assert(v[i] == false);
+    }
+  }
+  {
+    bool a[] = {true, false, true, false, true};
+    std::vector<bool> v(std::begin(a), std::end(a));
+    try {
+      v.resize(v.max_size() + 1, true);
+      assert(false);
+    } catch (const std::length_error&) {
+      assert(v.size() == 5);
+      assert(v.capacity() >= 5);
+      assert(std::equal(v.begin(), v.end(), std::begin(a)));
+    }
+  }
+}
+
+int main(int, char**) {
+  test();
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector/vector.capacity/reserve_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.capacity/reserve_exceptions.pass.cpp
index c381e23a04d02..129a52c97decd 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.capacity/reserve_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.capacity/reserve_exceptions.pass.cpp
@@ -8,6 +8,10 @@
 
 // UNSUPPORTED: no-exceptions
 
+// <vector>
+
+// void reserve(size_type n);
+
 // This test file validates that std::vector<T>::reserve provides the strong exception guarantee if T is
 // Cpp17MoveInsertable and no exception is thrown by the move constructor of T during the reserve call.
 // It also checks that if T's move constructor is not noexcept, reserve provides only the basic exception
@@ -36,7 +40,8 @@ void test_allocation_exception_for_strong_guarantee(
   std::size_t old_cap  = v.capacity();
 
   try {
-    v.reserve(new_cap);
+    v.reserve(new_cap); // Expected exception
+    assert(false);
   } catch (...) { // std::length_error, std::bad_alloc
     assert(v.data() == old_data);
     assert(v.size() == old_size);
@@ -61,7 +66,8 @@ void test_copy_ctor_exception_for_strong_guarantee(std::vector<throwing_data<T>,
   std::size_t new_cap        = 2 * old_cap;
 
   try {
-    v.reserve(new_cap);
+    v.reserve(new_cap); // Expected exception
+    assert(false);
   } catch (...) {
     assert(v.data() == old_data);
     assert(v.size() == old_size);
@@ -83,7 +89,8 @@ void test_move_ctor_exception_for_basic_guarantee(std::vector<move_only_throwing
     v.emplace_back(values[i], throw_after);
 
   try {
-    v.reserve(2 * v.capacity());
+    v.reserve(2 * v.capacity()); // Expected exception
+    assert(false);
   } catch (...) {
     use_unspecified_but_valid_state_vector(v);
   }
diff --git a/libcxx/test/std/containers/sequences/vector/vector.capacity/resize_size_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.capacity/resize_size_exceptions.pass.cpp
index b5e12ea8e5d0a..4aa19f8d89927 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.capacity/resize_size_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.capacity/resize_size_exceptions.pass.cpp
@@ -8,6 +8,10 @@
 
 // UNSUPPORTED: no-exceptions
 
+// <vector>
+
+// void resize(size_type sz);
+
 // This test file validates that std::vector<T>::resize(size_type) provides the strong exception guarantee
 // if no exception is thrown by the move constructor of T during the resize call. It also checks that if
 // T's move constructor is not noexcept, resize provides only the basic exception guarantee.
@@ -35,7 +39,8 @@ void test_allocation_exception_for_strong_guarantee(
   std::size_t old_cap  = v.capacity();
 
   try {
-    v.resize(new_size);
+    v.resize(new_size); // Expected exception
+    assert(false);
   } catch (...) { // std::length_error, std::bad_alloc
     assert(v.data() == old_data);
     assert(v.size() == old_size);
@@ -60,7 +65,8 @@ void test_default_ctor_exception_for_strong_guarantee(
   std::size_t new_size       = old_size + 1;
 
   try {
-    v.resize(new_size);
+    v.resize(new_size); // Expected exception
+    assert(false);
   } catch (...) {
     assert(v.data() == old_data);
     assert(v.size() == old_size);
@@ -85,7 +91,8 @@ void test_copy_ctor_exception_for_strong_guarantee(std::vector<throwing_data<T>,
   std::size_t new_size       = 2 * old_cap;
 
   try {
-    v.resize(new_size);
+    v.resize(new_size); // Expected exception
+    assert(false);
   } catch (...) {
     assert(v.data() == old_data);
     assert(v.size() == old_size);
@@ -107,7 +114,8 @@ void test_move_ctor_exception_for_basic_guarantee(std::vector<move_only_throwing
     v.emplace_back(values[i], throw_after);
 
   try {
-    v.resize(2 * v.capacity());
+    v.resize(2 * v.capacity()); // Expected exception
+    assert(false);
   } catch (...) {
     use_unspecified_but_valid_state_vector(v);
   }
diff --git a/libcxx/test/std/containers/sequences/vector/vector.capacity/resize_size_value_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.capacity/resize_size_value_exceptions.pass.cpp
index 7217b47d69e4d..3881d5f1b871b 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.capacity/resize_size_value_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.capacity/resize_size_value_exceptions.pass.cpp
@@ -8,6 +8,10 @@
 
 // UNSUPPORTED: no-exceptions
 
+// <vector>
+
+// void resize(size_type sz, const value_type& x);
+
 // Check that std::vector<T>::resize(size_type sz, const value_type& x) provides the strong exception guarantee
 // if T is Cpp17CopyInsertable.
 
@@ -33,7 +37,8 @@ void test_allocation_exception_for_strong_guarantee(
   std::size_t old_cap  = v.capacity();
 
   try {
-    v.resize(new_size, values.empty() ? T() : values[0]);
+    v.resize(new_size, values.empty() ? T() : values[0]); // Expected exception
+    assert(false);
   } catch (...) { // std::length_error, std::bad_alloc
     assert(v.data() == old_data);
     assert(v.size() == old_size);
@@ -60,7 +65,8 @@ void test_copy_ctor_exception_for_strong_guarantee(std::vector<throwing_data<T>,
   try {
     int n = new_size - old_size + 1;
     throwing_data<T> t(T(), n);
-    v.resize(new_size, t);
+    v.resize(new_size, t); // Expected exception
+    assert(false);
   } catch (...) {
     assert(v.data() == old_data);
     assert(v.size() == old_size);
diff --git a/libcxx/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit_exceptions.pass.cpp
index 521a25fdeda0f..9b316689b34b9 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit_exceptions.pass.cpp
@@ -8,6 +8,10 @@
 
 // UNSUPPORTED: no-exceptions
 
+// <vector>
+
+// void shrink_to_fit();
+
 // This test file validates that std::vector<T>::shrink_to_fit provides the strong exception guarantee when
 // T is Cpp17MoveInsertable and its move constructor does not throw exceptions during the shrink_to_fit
 // call. Additionally, it checks that for move-only types where T's move constructor is not noexcept, only
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range.pass.cpp
index 7a5031e4676f2..6353151c8391e 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range.pass.cpp
@@ -63,8 +63,5 @@ int main(int, char**) {
   test();
   static_assert(test());
 
-  test_append_range_exception_safety_throwing_copy<std::vector>();
-  test_append_range_exception_safety_throwing_allocator<std::vector, int>();
-
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range_exceptions.pass.cpp
new file mode 100644
index 0000000000000..4c89c5c293b1f
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range_exceptions.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+
+// template<container-compatible-range<T> R>
+//   constexpr void append_range(R&& rg); // C++23
+
+#include <cassert>
+#include <vector>
+
+#include "../../insert_range_sequence_containers.h"
+#include "test_allocator.h"
+
+void test() {
+  test_append_range_exception_safety_throwing_copy<std::vector>();
+  test_append_range_exception_safety_throwing_allocator<std::vector, int>();
+
+  {
+    std::vector<int, limited_allocator<int, 10> > v(8, 42);
+    int a[] = {1, 2, 3};
+    try {
+      v.append_range(a);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == 8);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+}
+
+int main(int, char**) {
+  test();
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back_exception_safety.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back_exception_safety.pass.cpp
new file mode 100644
index 0000000000000..d5823e6cec1b9
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back_exception_safety.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+
+// template <class... Args>
+//     reference emplace_back(Args&&... args); // reference in C++17
+
+#include <cassert>
+#include <vector>
+
+#include "test_allocator.h"
+
+int main(int, char**) {
+  std::vector<int, limited_allocator<int, 10> > v(10, 42);
+  try {
+    v.emplace_back(0);
+    assert(false);
+  } catch (...) {
+    assert(v.size() == v.max_size());
+    for (std::size_t i = 0; i != v.size(); ++i)
+      assert(v[i] == 42); // Strong exception safety guarantee
+  }
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_exceptions.pass.cpp
new file mode 100644
index 0000000000000..2a6c1e4391a82
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_exceptions.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+
+// template <class... Args> iterator emplace(const_iterator pos, Args&&... args);
+
+#include <cassert>
+#include <vector>
+
+#include "test_allocator.h"
+
+void test() {
+  {
+    std::vector<int, limited_allocator<int, 10> > v(10, 42);
+    try {
+      v.emplace(v.begin(), 0);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+  {
+    std::vector<int, limited_allocator<int, 10> > v(10, 42);
+    try {
+      v.emplace(v.end(), 0);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+  {
+    std::vector<int, limited_allocator<int, 10> > v(10, 42);
+    try {
+      v.emplace(v.begin() + v.size() / 2, 0);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+}
+
+int main(int, char**) {
+  test();
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_exceptions.pass.cpp
new file mode 100644
index 0000000000000..4dba3c49092fc
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_exceptions.pass.cpp
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+
+// iterator insert(const_iterator position, const value_type& x);
+// iterator insert(const_iterator position, size_type n, const value_type& x);
+// iterator insert(const_iterator p, initializer_list<value_type> il);
+// template <class Iter>
+//   iterator insert(const_iterator position, Iter first, Iter last);
+
+#include <cassert>
+#include <vector>
+
+#include "test_allocator.h"
+#include "test_macros.h"
+
+void test() {
+  {
+    std::vector<int, limited_allocator<int, 10> > v(10, 42);
+    try {
+      v.insert(v.begin(), 0);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+  {
+    std::vector<int, limited_allocator<int, 10> > v(10, 42);
+    try {
+      v.insert(v.end(), 0);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+  {
+    std::vector<int, limited_allocator<int, 10> > v(10, 42);
+    try {
+      v.insert(v.begin() + v.size() / 2, 0);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+  {
+    std::vector<int, limited_allocator<int, 10> > v(8, 42);
+    try {
+      v.insert(v.begin(), 3, 0);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == 8);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+  {
+    std::vector<int, limited_allocator<int, 10> > v(8, 42);
+    int a[] = {1, 2, 3};
+    try {
+      v.insert(v.begin() + v.size() / 2, std::begin(a), std::end(a));
+      assert(false);
+    } catch (...) {
+      assert(v.size() == 8);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+#if TEST_STD_VER >= 11
+  {
+    std::vector<int, limited_allocator<int, 10> > v(8, 42);
+    try {
+      v.insert(v.begin(), {1, 2, 3});
+      assert(false);
+    } catch (...) {
+      assert(v.size() == 8);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+#endif
+}
+
+int main(int, char**) {
+  test();
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range.pass.cpp
index ef63db083a998..c92280b8f5652 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range.pass.cpp
@@ -99,9 +99,6 @@ int main(int, char**) {
 
   static_assert(test_constraints_insert_range<std::vector, int, double>());
 
-  test_insert_range_exception_safety_throwing_copy<std::vector>();
-  test_insert_range_exception_safety_throwing_allocator<std::vector, int>();
-
 #ifndef TEST_HAS_NO_LOCALIZATION
   test_counted_istream_view();
 #endif
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range_exceptions.pass.cpp
new file mode 100644
index 0000000000000..4f0d23a182a77
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range_exceptions.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-exceptions
+
+// <vector>
+
+// template<container-compatible-range<T> R>
+//   constexpr iterator insert_range(const_iterator position, R&& rg); // C++23
+
+#include <cassert>
+#include <vector>
+
+#include "../../insert_range_sequence_containers.h"
+#include "test_allocator.h"
+
+void test() {
+  test_insert_range_exception_safety_throwing_copy<std::vector>();
+  test_insert_range_exception_safety_throwing_allocator<std::vector, int>();
+
+  {
+    std::vector<int, limited_allocator<int, 10> > v(8, 42);
+    int a[] = {1, 2, 3};
+    try {
+      v.insert_range(v.begin(), a);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == 8);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+  {
+    std::vector<int, limited_allocator<int, 10> > v(8, 42);
+    int a[] = {1, 2, 3};
+    try {
+      v.insert_range(v.end(), a);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == 8);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+  {
+    std::vector<int, limited_allocator<int, 10> > v(10, 42);
+    int a[] = {1, 2, 3};
+    try {
+      v.insert_range(v.begin() + v.size() / 2, a);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == 10);
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42);
+    }
+  }
+}
+
+int main(int, char**) {
+  test();
+
+  return 0;
+}
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
index cbdc55a700b75..d41577dc79a1c 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
@@ -10,10 +10,11 @@
 
 // void push_back(const value_type& x);
 
-#include <vector>
 #include <cassert>
+#include <vector>
 
 #include "asan_testing.h"
+#include "test_allocator.h"
 #include "test_macros.h"
 
 // Flag that makes the copy constructor for CMyClass throw an exception
@@ -86,6 +87,18 @@ int main(int, char**) {
     assert(vec == vec2);
     assert(is_contiguous_container_asan_correct(vec));
   }
+
+  {
+    std::vector<int, limited_allocator<int, 10> > v(10, 42);
+    try {
+      v.push_back(0);
+      assert(false);
+    } catch (...) {
+      assert(v.size() == v.max_size());
+      for (std::size_t i = 0; i != v.size(); ++i)
+        assert(v[i] == 42); // Strong exception safety guarantee
+    }
+  }
 #endif
 
   return 0;

>From 25f7a6aca7d22b4710faece690af71b110ab4853 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Fri, 20 Jun 2025 10:57:44 -0400
Subject: [PATCH 2/2] Address ldionne's comments

---
 .../vector.bool/append_range.pass.cpp         | 10 +++++
 .../append_range_exceptions.pass.cpp          | 19 ++++----
 .../emplace_back_exceptions.pass.cpp          |  7 +--
 .../vector.bool/emplace_exceptions.pass.cpp   | 25 +++++------
 .../vector.bool/insert_exceptions.pass.cpp    | 43 +++++++++----------
 .../insert_range_exceptions.pass.cpp          | 23 +++++-----
 .../vector.bool/push_back_exceptions.pass.cpp |  7 +--
 .../vector.bool/reserve_exceptions.pass.cpp   |  9 ++--
 .../resize_size_exceptions.pass.cpp           | 12 ++----
 .../resize_size_value_exceptions.pass.cpp     | 13 ++----
 .../append_range_exceptions.pass.cpp          |  9 ++--
 .../emplace_back_exception_safety.pass.cpp    |  3 +-
 .../emplace_exceptions.pass.cpp               | 13 +++---
 .../insert_exceptions.pass.cpp                | 19 ++++----
 .../insert_range_exceptions.pass.cpp          | 13 +++---
 .../push_back_exception_safety.pass.cpp       |  3 +-
 16 files changed, 101 insertions(+), 127 deletions(-)

diff --git a/libcxx/test/std/containers/sequences/vector.bool/append_range.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/append_range.pass.cpp
index 8dea772375490..c410b11a2308f 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/append_range.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/append_range.pass.cpp
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "../insert_range_sequence_containers.h"
+#include "test_allocator.h"
 #include "test_macros.h"
 
 // Tested cases:
@@ -56,6 +57,15 @@ constexpr bool test() {
       v.append_range(in);
       assert(std::ranges::equal(v, std::vector<bool>{0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1}));
     }
+
+    { // Ensure that appending an empty range has no effect
+      std::vector<bool, limited_allocator<bool, 10> > v;
+      v.resize(v.max_size(), true);
+      std::vector<bool> a;
+      v.append_range(a);
+      for (std::size_t i = 0; i < v.size(); ++i)
+        assert(v[i] == true);
+    }
   }
 
   return true;
diff --git a/libcxx/test/std/containers/sequences/vector.bool/append_range_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/append_range_exceptions.pass.cpp
index 63f23926f5f0e..0ec4b13887681 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/append_range_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/append_range_exceptions.pass.cpp
@@ -16,18 +16,19 @@
 //   constexpr void append_range(R&& rg); // C++23
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "../insert_range_sequence_containers.h"
 #include "test_allocator.h"
 
-void test() {
+int main(int, char**) {
   // Note: `test_append_range_exception_safety_throwing_copy` doesn't apply because copying booleans cannot throw.
   test_append_range_exception_safety_throwing_allocator<std::vector, bool>();
 
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size() - 2, true);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size() - 2, true);
     bool a[] = {false, true, false};
     try {
       v.append_range(a);
@@ -39,21 +40,17 @@ void test() {
     }
   }
   {
-    std::vector<bool, limited_allocator<bool, 10> > v(10, true);
-    bool a[10 * 65536] = {};
+    std::vector<bool, limited_allocator<bool, 10> > v(5, true);
+    bool a[v.max_size()] = {}; // A large enough array to trigger a length_error when appended
     try {
       v.append_range(a);
       assert(false);
-    } catch (...) {
-      assert(v.size() == 10);
+    } catch (const std::length_error&) {
+      assert(v.size() == 5);
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == true);
     }
   }
-}
-
-int main(int, char**) {
-  test();
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector.bool/emplace_back_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/emplace_back_exceptions.pass.cpp
index fb8504b60acd9..459dffda5635c 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/emplace_back_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/emplace_back_exceptions.pass.cpp
@@ -16,17 +16,18 @@
 //     reference emplace_back(Args&&... args); // reference in C++17
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "test_allocator.h"
 
 int main(int, char**) {
-  using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-  Vec v(Vec().max_size(), true);
+  std::vector<bool, limited_allocator<bool, 10> > v;
+  v.resize(v.max_size(), true);
   try {
     v.emplace_back(true);
     assert(false);
-  } catch (...) {
+  } catch (const std::length_error&) {
     assert(v.size() == v.max_size());
     for (std::size_t i = 0; i != v.size(); ++i)
       assert(v[i] == true);
diff --git a/libcxx/test/std/containers/sequences/vector.bool/emplace_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/emplace_exceptions.pass.cpp
index 5daea125fc555..e8e62e7a61286 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/emplace_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/emplace_exceptions.pass.cpp
@@ -15,51 +15,48 @@
 // template <class... Args> iterator emplace(const_iterator pos, Args&&... args);
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "test_allocator.h"
 
-void test() {
+int main(int, char**) {
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size(), true);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size(), true);
     try {
       v.emplace(v.begin(), true);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == true);
     }
   }
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size(), true);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size(), true);
     try {
       v.emplace(v.end(), true);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == true);
     }
   }
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size(), true);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size(), true);
     try {
       v.emplace(v.begin() + v.size() / 2, true);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == true);
     }
   }
-}
-
-int main(int, char**) {
-  test();
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector.bool/insert_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/insert_exceptions.pass.cpp
index a9742ffe2a5a3..b7b06769968ec 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/insert_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/insert_exceptions.pass.cpp
@@ -18,68 +18,69 @@
 //   iterator insert(const_iterator position, Iter first, Iter last);
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "test_allocator.h"
 #include "test_macros.h"
 
-void test() {
+int main(int, char**) {
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size(), true);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size(), true);
     try {
       v.insert(v.begin(), false);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == true);
     }
   }
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size(), false);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size(), false);
     try {
       v.insert(v.end(), 0);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == false);
     }
   }
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size(), true);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size(), true);
     try {
       v.insert(v.begin() + v.size() / 2, false);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == true);
     }
   }
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size(), true);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size(), true);
     try {
       v.insert(v.begin(), 1, false);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == true);
     }
   }
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size() - 2, true);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size() - 2, true);
     bool a[] = {true, false, true};
     try {
       v.insert(v.begin() + v.size() / 2, std::begin(a), std::end(a));
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size() - 2);
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == true);
@@ -87,22 +88,18 @@ void test() {
   }
 #if TEST_STD_VER >= 11
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size() - 2, true);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size() - 2, true);
     try {
       v.insert(v.begin(), {true, false, true});
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size() - 2);
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == true);
     }
   }
 #endif
-}
-
-int main(int, char**) {
-  test();
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector.bool/insert_range_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/insert_range_exceptions.pass.cpp
index c521d91d26c1d..a5c6589d9e2c4 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/insert_range_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/insert_range_exceptions.pass.cpp
@@ -16,18 +16,19 @@
 //   constexpr iterator insert_range(const_iterator position, R&& rg); // C++23
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "../insert_range_sequence_containers.h"
 #include "test_allocator.h"
 
-void test() {
+int main(int, char**) {
   // Note: `test_insert_range_exception_safety_throwing_copy` doesn't apply because copying booleans cannot throw.
   test_insert_range_exception_safety_throwing_allocator<std::vector, bool>();
 
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size() - 2, true);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size() - 2, true);
     bool a[] = {true, false, true};
     try {
       v.insert_range(v.end(), a);
@@ -39,8 +40,8 @@ void test() {
     }
   }
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size() - 2, false);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size() - 2, false);
     bool a[] = {true, false, true};
     try {
       v.insert_range(v.begin(), a);
@@ -52,21 +53,17 @@ void test() {
     }
   }
   {
-    std::vector<bool, limited_allocator<bool, 10> > v(10, true);
-    bool a[10 * 65536] = {};
+    std::vector<bool, limited_allocator<bool, 10> > v(5, true);
+    bool a[v.max_size()] = {};
     try {
       v.insert_range(v.begin() + v.size() / 2, a);
       assert(false);
-    } catch (...) {
-      assert(v.size() == 10);
+    } catch (const std::length_error&) {
+      assert(v.size() == 5);
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == true);
     }
   }
-}
-
-int main(int, char**) {
-  test();
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector.bool/push_back_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/push_back_exceptions.pass.cpp
index 272325bec1768..0b93c66aed0fe 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/push_back_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/push_back_exceptions.pass.cpp
@@ -14,17 +14,18 @@
 // void push_back(const value_type& x);
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "test_allocator.h"
 
 int main(int, char**) {
-  using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-  Vec v(Vec().max_size(), true);
+  std::vector<bool, limited_allocator<bool, 10> > v;
+  v.resize(v.max_size(), true);
   try {
     v.push_back(true);
     assert(false);
-  } catch (...) {
+  } catch (const std::length_error&) {
     assert(v.size() == v.max_size());
     for (std::size_t i = 0; i != v.size(); ++i)
       assert(v[i] == true);
diff --git a/libcxx/test/std/containers/sequences/vector.bool/reserve_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/reserve_exceptions.pass.cpp
index 8dc31251bc73a..255c11522ebf8 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/reserve_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/reserve_exceptions.pass.cpp
@@ -19,7 +19,7 @@
 
 #include "test_allocator.h"
 
-void test() {
+int main(int, char**) {
   {
     std::vector<bool, limited_allocator<bool, 10> > v;
     v.reserve(5);
@@ -36,8 +36,8 @@ void test() {
     }
   }
   {
-    using Vec = std::vector<bool, limited_allocator<bool, 10> >;
-    Vec v(Vec().max_size(), true);
+    std::vector<bool, limited_allocator<bool, 10> > v;
+    v.resize(v.max_size(), true);
     try {
       v.reserve(v.max_size() + 1);
       assert(false);
@@ -60,9 +60,6 @@ void test() {
         assert(v[i] == a[i]);
     }
   }
-}
 
-int main(int, char**) {
-  test();
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector.bool/resize_size_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/resize_size_exceptions.pass.cpp
index 8a1539e40649c..1f3e0a51b56e1 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/resize_size_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/resize_size_exceptions.pass.cpp
@@ -20,14 +20,11 @@
 
 #include "test_allocator.h"
 
-void test() {
+int main(int, char**) {
   {
-    std::vector<bool, limited_allocator<bool, 10> > v;
-    v.resize(5);
+    std::vector<bool, limited_allocator<bool, 10> > v(5, false);
     try {
-      // It is reasonable to assume that no vector<bool> implementation would use
-      // 64 kB or larger chunk size for the underlying bits storage.
-      v.resize(10 * 65536); // 10 * max_chunk_size
+      v.resize(v.max_size() + 1);
       assert(false);
     } catch (const std::length_error&) {
       assert(v.size() == 5);
@@ -60,9 +57,6 @@ void test() {
       assert(std::equal(v.begin(), v.end(), std::begin(a)));
     }
   }
-}
 
-int main(int, char**) {
-  test();
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector.bool/resize_size_value_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/resize_size_value_exceptions.pass.cpp
index 6af3c9ac8fa1a..f96bf6f8e93a5 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/resize_size_value_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/resize_size_value_exceptions.pass.cpp
@@ -22,14 +22,11 @@
 #include "../insert_range_sequence_containers.h"
 #include "test_allocator.h"
 
-void test() {
+int main(int, char**) {
   {
-    std::vector<bool, limited_allocator<bool, 10> > v;
-    v.resize(5);
+    std::vector<bool, limited_allocator<bool, 10> > v(5, false);
     try {
-      // It is reasonable to assume that no vector<bool> implementation would use
-      // 64 kB or larger chunk size for the underlying bits storage.
-      v.resize(10 * 65536, true); // 10 * max_chunk_size
+      v.resize(v.max_size() + 1, true);
       assert(false);
     } catch (const std::length_error&) {
       assert(v.size() == 5);
@@ -62,10 +59,6 @@ void test() {
       assert(std::equal(v.begin(), v.end(), std::begin(a)));
     }
   }
-}
-
-int main(int, char**) {
-  test();
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range_exceptions.pass.cpp
index 4c89c5c293b1f..4511c872c53db 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range_exceptions.pass.cpp
@@ -15,12 +15,13 @@
 //   constexpr void append_range(R&& rg); // C++23
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "../../insert_range_sequence_containers.h"
 #include "test_allocator.h"
 
-void test() {
+int main(int, char**) {
   test_append_range_exception_safety_throwing_copy<std::vector>();
   test_append_range_exception_safety_throwing_allocator<std::vector, int>();
 
@@ -30,16 +31,12 @@ void test() {
     try {
       v.append_range(a);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == 8);
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
     }
   }
-}
-
-int main(int, char**) {
-  test();
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back_exception_safety.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back_exception_safety.pass.cpp
index d5823e6cec1b9..fdb600a8bc9a0 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back_exception_safety.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_back_exception_safety.pass.cpp
@@ -15,6 +15,7 @@
 //     reference emplace_back(Args&&... args); // reference in C++17
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "test_allocator.h"
@@ -24,7 +25,7 @@ int main(int, char**) {
   try {
     v.emplace_back(0);
     assert(false);
-  } catch (...) {
+  } catch (const std::length_error&) {
     assert(v.size() == v.max_size());
     for (std::size_t i = 0; i != v.size(); ++i)
       assert(v[i] == 42); // Strong exception safety guarantee
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_exceptions.pass.cpp
index 2a6c1e4391a82..5630e87b335b3 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace_exceptions.pass.cpp
@@ -14,17 +14,18 @@
 // template <class... Args> iterator emplace(const_iterator pos, Args&&... args);
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "test_allocator.h"
 
-void test() {
+int main(int, char**) {
   {
     std::vector<int, limited_allocator<int, 10> > v(10, 42);
     try {
       v.emplace(v.begin(), 0);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
@@ -35,7 +36,7 @@ void test() {
     try {
       v.emplace(v.end(), 0);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
@@ -46,16 +47,12 @@ void test() {
     try {
       v.emplace(v.begin() + v.size() / 2, 0);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
     }
   }
-}
-
-int main(int, char**) {
-  test();
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_exceptions.pass.cpp
index 4dba3c49092fc..787bb791be2b9 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_exceptions.pass.cpp
@@ -17,18 +17,19 @@
 //   iterator insert(const_iterator position, Iter first, Iter last);
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "test_allocator.h"
 #include "test_macros.h"
 
-void test() {
+int main(int, char**) {
   {
     std::vector<int, limited_allocator<int, 10> > v(10, 42);
     try {
       v.insert(v.begin(), 0);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
@@ -39,7 +40,7 @@ void test() {
     try {
       v.insert(v.end(), 0);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
@@ -50,7 +51,7 @@ void test() {
     try {
       v.insert(v.begin() + v.size() / 2, 0);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
@@ -61,7 +62,7 @@ void test() {
     try {
       v.insert(v.begin(), 3, 0);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == 8);
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
@@ -73,7 +74,7 @@ void test() {
     try {
       v.insert(v.begin() + v.size() / 2, std::begin(a), std::end(a));
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == 8);
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
@@ -85,17 +86,13 @@ void test() {
     try {
       v.insert(v.begin(), {1, 2, 3});
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == 8);
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
     }
   }
 #endif
-}
-
-int main(int, char**) {
-  test();
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range_exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range_exceptions.pass.cpp
index 4f0d23a182a77..77848af265e1b 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range_exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range_exceptions.pass.cpp
@@ -15,12 +15,13 @@
 //   constexpr iterator insert_range(const_iterator position, R&& rg); // C++23
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "../../insert_range_sequence_containers.h"
 #include "test_allocator.h"
 
-void test() {
+int main(int, char**) {
   test_insert_range_exception_safety_throwing_copy<std::vector>();
   test_insert_range_exception_safety_throwing_allocator<std::vector, int>();
 
@@ -30,7 +31,7 @@ void test() {
     try {
       v.insert_range(v.begin(), a);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == 8);
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
@@ -42,7 +43,7 @@ void test() {
     try {
       v.insert_range(v.end(), a);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == 8);
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
@@ -54,16 +55,12 @@ void test() {
     try {
       v.insert_range(v.begin() + v.size() / 2, a);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == 10);
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42);
     }
   }
-}
-
-int main(int, char**) {
-  test();
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
index d41577dc79a1c..6dc9719afb556 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
@@ -11,6 +11,7 @@
 // void push_back(const value_type& x);
 
 #include <cassert>
+#include <stdexcept>
 #include <vector>
 
 #include "asan_testing.h"
@@ -93,7 +94,7 @@ int main(int, char**) {
     try {
       v.push_back(0);
       assert(false);
-    } catch (...) {
+    } catch (const std::length_error&) {
       assert(v.size() == v.max_size());
       for (std::size_t i = 0; i != v.size(); ++i)
         assert(v[i] == 42); // Strong exception safety guarantee



More information about the libcxx-commits mailing list