[libcxx-commits] [libcxx] [libc++][vector] Make constructor vector(count, value, allocator) exception-safe (PR #82033)
Mateusz Zych via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Feb 16 15:44:48 PST 2024
https://github.com/mtezych updated https://github.com/llvm/llvm-project/pull/82033
>From 7ff58b52a916bf4c64be0be2e84dff11668d3de4 Mon Sep 17 00:00:00 2001
From: Mateusz Zych <mte.zych at gmail.com>
Date: Fri, 16 Feb 2024 23:35:10 +0300
Subject: [PATCH 1/2] [libc++][vector] Make constructor vector(count, value,
allocator) exception-safe
---
libcxx/include/vector | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libcxx/include/vector b/libcxx/include/vector
index ce7df7a9f04207..c3e3f05671f8fa 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -433,10 +433,12 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
vector(size_type __n, const value_type& __x, const allocator_type& __a)
: __end_cap_(nullptr, __a) {
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
if (__n > 0) {
__vallocate(__n);
__construct_at_end(__n, __x);
}
+ __guard.__complete();
}
template <class _InputIterator,
>From 8bb312934ccfc3dae276e88d7d698fffaf848a13 Mon Sep 17 00:00:00 2001
From: Mateusz Zych <mte.zych at gmail.com>
Date: Fri, 16 Feb 2024 21:48:15 +0300
Subject: [PATCH 2/2] exception safety tests for constructors of std::vector
---
.../vector/vector.cons/exceptions.pass.cpp | 26 ++++++++++++++++---
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp
index 3ef5aeecc1b0c9..0bf632292ea1d0 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp
@@ -41,6 +41,7 @@ struct Allocator {
struct ThrowingT {
int* throw_after_n_ = nullptr;
+
ThrowingT() { throw 0; }
ThrowingT(int& throw_after_n) : throw_after_n_(&throw_after_n) {
@@ -104,6 +105,7 @@ void check_new_delete_called() {
int main(int, char**) {
using AllocVec = std::vector<int, Allocator<int> >;
+
try { // vector()
AllocVec vec;
} catch (int) {
@@ -111,23 +113,23 @@ int main(int, char**) {
check_new_delete_called();
try { // Throw in vector(size_type) from type
- std::vector<ThrowingT> get_alloc(1);
+ std::vector<ThrowingT> vec(1);
} catch (int) {
}
check_new_delete_called();
#if TEST_STD_VER >= 14
- try { // Throw in vector(size_type, value_type) from type
+ try { // Throw in vector(size_type, const value_type&) from type
int throw_after = 1;
ThrowingT v(throw_after);
- std::vector<ThrowingT> get_alloc(1, v);
+ std::vector<ThrowingT> vec(1, v);
} catch (int) {
}
check_new_delete_called();
try { // Throw in vector(size_type, const allocator_type&) from allocator
Allocator<int> alloc(false);
- AllocVec get_alloc(0, alloc);
+ AllocVec vec(0, alloc);
} catch (int) {
}
check_new_delete_called();
@@ -137,6 +139,22 @@ int main(int, char**) {
} catch (int) {
}
check_new_delete_called();
+
+ // https://github.com/llvm/llvm-project/commit/8ff4d218a80b887bb645ec426aefa1ab7144c5f3
+ // https://github.com/llvm/llvm-project/commit/7da4ee6f23dd14464ee869caec18b5421d1cf7ca
+ // https://godbolt.org/z/E47aYG8Mj
+ // https://github.com/llvm/llvm-project/issues/59651
+ // https://github.com/llvm/llvm-project/issues/58392
+
+ try { // Throw in vector(size_type, const value_type&, const allocator_type&) from allocator
+ } catch (int) {
+ }
+ check_new_delete_called();
+
+ try { // Throw in vector(size_type, const value_type&, const allocator_type&) from the type
+ } catch (int) {
+ }
+ check_new_delete_called();
#endif // TEST_STD_VER >= 14
try { // Throw in vector(InputIterator, InputIterator) from input iterator
More information about the libcxx-commits
mailing list