~_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
private:
_UninitDestroyGuard(const _UninitDestroyGuard&);
+
+#if __cplusplus == 201703L
+ template<typename _Iter>
+ 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
};
// This is the default implementation of std::uninitialized_copy.
--- /dev/null
+// { dg-do compile { target c++17 } }
+
+#include <memory>
+
+// PR libstdc++/120397
+// std::uninitialized_value_construct cannot create arrays of non-trivially
+// destructible types
+
+struct X { X() { } ~X() { } };
+
+void def(X (*x)[1])
+{
+ std::uninitialized_default_construct(x, x+1);
+}
+
+void def_n(X (*x)[1])
+{
+ std::uninitialized_default_construct_n(x, 1);
+}
--- /dev/null
+// { dg-do compile { target c++17 } }
+
+#include <memory>
+
+// PR libstdc++/120397
+// std::uninitialized_value_construct cannot create arrays of non-trivially
+// destructible types
+
+struct X { X() { } ~X() { } };
+
+void val(X (*x)[1])
+{
+ std::uninitialized_value_construct(x, x+1);
+}
+
+void val_n(X (*x)[1])
+{
+ std::uninitialized_value_construct_n(x, 1);
+}