[gcc r16-819] libstdc++: Fix vector(from_range_t, R&&) for exceptions [PR120367]
Jonathan Wakely
redi@gcc.gnu.org
Thu May 22 11:14:54 GMT 2025
https://gcc.gnu.org/g:04f2be72b1deecd6c6d454e000cfc0cb16db957c
commit r16-819-g04f2be72b1deecd6c6d454e000cfc0cb16db957c
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Wed May 21 15:29:02 2025 +0100
libstdc++: Fix vector(from_range_t, R&&) for exceptions [PR120367]
Because this constructor delegates to vector(a) the object has been
fully constructed and the destructor will run if an exception happens.
That means we need to set _M_finish == _M_start so that the destructor
doesn't try to destroy any elements.
libstdc++-v3/ChangeLog:
PR libstdc++/120367
* include/bits/stl_vector.h (_M_range_initialize): Initialize
_M_impl._M_finish.
* testsuite/23_containers/vector/cons/from_range.cc: Check with
a type that throws on construction.
exceptions during construction.
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Diff:
---
libstdc++-v3/include/bits/stl_vector.h | 3 ++-
.../23_containers/vector/cons/from_range.cc | 22 ++++++++++++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 57680b7bbcf3..625c1c93195e 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1969,8 +1969,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_range_initialize_n(_Iterator __first, _Sentinel __last,
size_type __n)
{
- pointer __start = this->_M_impl._M_start =
+ pointer __start =
this->_M_allocate(_S_check_init_len(__n, _M_get_Tp_allocator()));
+ this->_M_impl._M_start = this->_M_impl._M_finish = __start;
this->_M_impl._M_end_of_storage = __start + __n;
this->_M_impl._M_finish
= std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last,
diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
index 7a62645283d2..3784b9cd66ad 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
@@ -106,8 +106,30 @@ test_constexpr()
return true;
}
+void
+test_pr120367()
+{
+#ifdef __cpp_exceptions
+ struct X
+ {
+ X(int) { throw 1; } // Cannot successfully construct an X.
+ ~X() { VERIFY(false); } // So should never need to destroy one.
+ };
+
+ try
+ {
+ int i[1]{};
+ std::vector<X> v(std::from_range, i);
+ }
+ catch (int)
+ {
+ }
+#endif
+}
+
int main()
{
test_ranges();
static_assert( test_constexpr() );
+ test_pr120367();
}
More information about the Libstdc++-cvs
mailing list