[PATCH] libstdc++: Fix vector(from_range_t, R&&) for exceptions [PR120367]
Jonathan Wakely
jwakely.gcc@gmail.com
Thu May 22 07:10:57 GMT 2025
On Thu, 22 May 2025, 07:21 Tomasz Kaminski, <tkaminsk@redhat.com> wrote:
>
>
> On Wed, May 21, 2025 at 5:41 PM Jonathan Wakely <jwakely@redhat.com>
> wrote:
>
>> 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.
>> ---
>>
>> Tested x86_64-linux.
>>
>> libstdc++-v3/include/bits/stl_vector.h | 1 +
>> .../23_containers/vector/cons/from_range.cc | 22 +++++++++++++++++++
>> 2 files changed, 23 insertions(+)
>>
>> diff --git a/libstdc++-v3/include/bits/stl_vector.h
>> b/libstdc++-v3/include/bits/stl_vector.h
>> index 57680b7bbcf3..43b913da778d 100644
>> --- a/libstdc++-v3/include/bits/stl_vector.h
>> +++ b/libstdc++-v3/include/bits/stl_vector.h
>> @@ -1971,6 +1971,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>> {
>> pointer __start = this->_M_impl._M_start =
>>
> Not required change, but I was a bit confused where _M_start is set.
> Maybe assign all pointers here?
> pointer __start = this->_M_impl._M_start =
> this->_M_impl._M_finish =
>
That's how I wrote it at
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120367#c4 but it seemed a bit
crowded so I did it on a separate line for the real patch.
this->_M_allocate(_S_check_init_len(__n,
>> _M_get_Tp_allocator()));
>> + 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();
>> }
>> --
>> 2.49.0
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250522/08659072/attachment.htm>
More information about the Libstdc++
mailing list