On Fri, 13 Jun 2025 at 10:38, Daniel Krügler <daniel.krueg...@gmail.com> wrote: > > Am Fr., 13. Juni 2025 um 11:33 Uhr schrieb Jonathan Wakely > <jwak...@redhat.com>: >> >> The std::uninitialized_{value,default}_construct{,_n} algorithms should >> be able to create arrays, but that currently fails because when an >> exception happens they clean up using std::_Destroy and in C++17 that >> doesn't support destroying arrays. (For C++20 and later, std::destroy >> does handle destroying arrays.) >> >> This commit adjusts the _UninitDestroyGuard RAII type used by those >> algos so that in C++17 mode it recursively destroys each rank of an >> array type, only using std::_Destroy for the last rank when it's >> destroying non-array objects. >> >> libstdc++-v3/ChangeLog: >> >> PR libstdc++/120397 >> * include/bits/stl_uninitialized.h (_UninitDestroyGuard<I,void>): >> Add new member function _S_destroy and call it from the >> destructor (for C++17 only). >> * >> testsuite/20_util/specialized_algorithms/uninitialized_default_construct/120397.cc: >> New test. >> * >> testsuite/20_util/specialized_algorithms/uninitialized_value_construct/120397.cc: >> New test. >> --- >> >> v2: Only define+use _S_destroy for C++17, at Tomasz's request. >> >> Tested x86_64-linux. >> >> libstdc++-v3/include/bits/stl_uninitialized.h | 21 +++++++++++++++++++ >> .../uninitialized_default_construct/120397.cc | 19 +++++++++++++++++ >> .../uninitialized_value_construct/120397.cc | 19 +++++++++++++++++ >> 3 files changed, 59 insertions(+) >> create mode 100644 >> libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/120397.cc >> create mode 100644 >> libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/120397.cc >> >> diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h >> b/libstdc++-v3/include/bits/stl_uninitialized.h >> index bde787c2beaa..4b3f81604606 100644 >> --- a/libstdc++-v3/include/bits/stl_uninitialized.h >> +++ b/libstdc++-v3/include/bits/stl_uninitialized.h >> @@ -118,7 +118,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >> ~_UninitDestroyGuard() >> { >> if (__builtin_expect(_M_cur != 0, 0)) >> +#if __cplusplus == 201703L >> + // std::uninitialized_{value,default}{,_n} can construct array >> types, >> + // but std::_Destroy cannot handle them until C++20 (PR 120397). >> + _S_destroy(_M_first, *_M_cur); >> +#else >> std::_Destroy(_M_first, *_M_cur); >> +#endif >> } >> >> _GLIBCXX20_CONSTEXPR >> @@ -129,6 +135,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >> >> private: >> _UninitDestroyGuard(const _UninitDestroyGuard&); >> + >> +#if __cplusplus == 201703L >> + template<typename _Iter> >> + _GLIBCXX20_CONSTEXPR > > > Since this signature *only* targets C++17, what is the purpose of the > _GLIBCXX20_CONSTEXPR ?
It's just a leftover from the previous patch, I'll remove it, thanks. > >> >> + static void >> + _S_destroy(_Iter __first, _Iter __last) >> + { >> + using _ValT = typename iterator_traits<_Iter>::value_type; >> + if constexpr (is_array<_ValT>::value) >> + for (; __first != __last; ++__first) >> + _S_destroy(*__first, *__first + extent<_ValT>::value); >> + else >> + std::_Destroy(__first, __last); >> + } >> +#endif >> }; >> > > - Daniel > >