Commit 0f317ef7 by Marc Glisse Committed by Marc Glisse

Relocation (= move+destroy)

2018-10-25  Marc Glisse  <marc.glisse@inria.fr>

	PR libstdc++/87106
	* include/bits/alloc_traits.h (_S_construct, _S_destroy, construct,
	destroy): Add noexcept specification.
	* include/bits/allocator.h (construct, destroy): Likewise.
	* include/ext/alloc_traits.h (construct, destroy): Likewise.
	* include/ext/malloc_allocator.h (construct, destroy): Likewise.
	* include/ext/new_allocator.h (construct, destroy): Likewise.
	* include/bits/stl_uninitialized.h (__relocate_object_a, __relocate_a,
	__relocate_a_1): New functions.
	(__is_trivially_relocatable): New class.
	* include/bits/stl_vector.h (__use_relocate): New static member.
	* include/bits/vector.tcc (reserve, _M_realloc_insert,
	_M_default_append): Use __relocate_a.
	(reserve, _M_assign_aux, _M_realloc_insert, _M_fill_insert,
	_M_default_append, _M_range_insert): Move _GLIBCXX_ASAN_ANNOTATE_REINIT
	after _Destroy.
	* testsuite/23_containers/vector/modifiers/push_back/49836.cc:
	Replace CopyConsOnlyType with DelAnyAssign.

From-SVN: r265485
parent 09d3f04e
2018-10-25 Marc Glisse <marc.glisse@inria.fr>
PR libstdc++/87106
* include/bits/alloc_traits.h (_S_construct, _S_destroy, construct,
destroy): Add noexcept specification.
* include/bits/allocator.h (construct, destroy): Likewise.
* include/ext/alloc_traits.h (construct, destroy): Likewise.
* include/ext/malloc_allocator.h (construct, destroy): Likewise.
* include/ext/new_allocator.h (construct, destroy): Likewise.
* include/bits/stl_uninitialized.h (__relocate_object_a, __relocate_a,
__relocate_a_1): New functions.
(__is_trivially_relocatable): New class.
* include/bits/stl_vector.h (__use_relocate): New static member.
* include/bits/vector.tcc (reserve, _M_realloc_insert,
_M_default_append): Use __relocate_a.
(reserve, _M_assign_aux, _M_realloc_insert, _M_fill_insert,
_M_default_append, _M_range_insert): Move _GLIBCXX_ASAN_ANNOTATE_REINIT
after _Destroy.
* testsuite/23_containers/vector/modifiers/push_back/49836.cc:
Replace CopyConsOnlyType with DelAnyAssign.
2018-10-24 François Dumont <fdumont@gcc.gnu.org> 2018-10-24 François Dumont <fdumont@gcc.gnu.org>
* include/debug/safe_unordered_container.h * include/debug/safe_unordered_container.h
......
...@@ -240,6 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -240,6 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename... _Args> template<typename _Tp, typename... _Args>
static _Require<__has_construct<_Tp, _Args...>> static _Require<__has_construct<_Tp, _Args...>>
_S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args) _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
{ __a.construct(__p, std::forward<_Args>(__args)...); } { __a.construct(__p, std::forward<_Args>(__args)...); }
template<typename _Tp, typename... _Args> template<typename _Tp, typename... _Args>
...@@ -247,17 +248,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -247,17 +248,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Require<__and_<__not_<__has_construct<_Tp, _Args...>>, _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
is_constructible<_Tp, _Args...>>> is_constructible<_Tp, _Args...>>>
_S_construct(_Alloc&, _Tp* __p, _Args&&... __args) _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
noexcept(noexcept(::new((void*)__p)
_Tp(std::forward<_Args>(__args)...)))
{ ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); } { ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); }
template<typename _Alloc2, typename _Tp> template<typename _Alloc2, typename _Tp>
static auto static auto
_S_destroy(_Alloc2& __a, _Tp* __p, int) _S_destroy(_Alloc2& __a, _Tp* __p, int)
noexcept(noexcept(__a.destroy(__p)))
-> decltype(__a.destroy(__p)) -> decltype(__a.destroy(__p))
{ __a.destroy(__p); } { __a.destroy(__p); }
template<typename _Alloc2, typename _Tp> template<typename _Alloc2, typename _Tp>
static void static void
_S_destroy(_Alloc2&, _Tp* __p, ...) _S_destroy(_Alloc2&, _Tp* __p, ...)
noexcept(noexcept(__p->~_Tp()))
{ __p->~_Tp(); } { __p->~_Tp(); }
template<typename _Alloc2> template<typename _Alloc2>
...@@ -340,6 +345,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -340,6 +345,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/ */
template<typename _Tp, typename... _Args> template<typename _Tp, typename... _Args>
static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args) static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
noexcept(noexcept(_S_construct(__a, __p,
std::forward<_Args>(__args)...)))
-> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...)) -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
{ _S_construct(__a, __p, std::forward<_Args>(__args)...); } { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
...@@ -353,6 +360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -353,6 +360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/ */
template<typename _Tp> template<typename _Tp>
static void destroy(_Alloc& __a, _Tp* __p) static void destroy(_Alloc& __a, _Tp* __p)
noexcept(noexcept(_S_destroy(__a, __p, 0)))
{ _S_destroy(__a, __p, 0); } { _S_destroy(__a, __p, 0); }
/** /**
...@@ -472,6 +480,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -472,6 +480,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Up, typename... _Args> template<typename _Up, typename... _Args>
static void static void
construct(allocator_type& __a, _Up* __p, _Args&&... __args) construct(allocator_type& __a, _Up* __p, _Args&&... __args)
noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
{ __a.construct(__p, std::forward<_Args>(__args)...); } { __a.construct(__p, std::forward<_Args>(__args)...); }
/** /**
...@@ -484,6 +493,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -484,6 +493,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Up> template<typename _Up>
static void static void
destroy(allocator_type& __a, _Up* __p) destroy(allocator_type& __a, _Up* __p)
noexcept(noexcept(__a.destroy(__p)))
{ __a.destroy(__p); } { __a.destroy(__p); }
/** /**
......
...@@ -88,11 +88,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -88,11 +88,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Up, typename... _Args> template<typename _Up, typename... _Args>
void void
construct(_Up* __p, _Args&&... __args) construct(_Up* __p, _Args&&... __args)
noexcept(noexcept(::new((void *)__p)
_Up(std::forward<_Args>(__args)...)))
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
template<typename _Up> template<typename _Up>
void void
destroy(_Up* __p) { __p->~_Up(); } destroy(_Up* __p)
noexcept(noexcept(__p->~_Up()))
{ __p->~_Up(); }
#endif #endif
}; };
......
...@@ -879,6 +879,68 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -879,6 +879,68 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
#endif #endif
#if __cplusplus >= 201103L
template<typename _Tp, typename _Up, typename _Allocator>
inline void
__relocate_object_a(_Tp* __dest, _Up* __orig, _Allocator& __alloc)
noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc,
__dest, std::move(*__orig)))
&& noexcept(std::allocator_traits<_Allocator>::destroy(
__alloc, std::__addressof(*__orig))))
{
typedef std::allocator_traits<_Allocator> __traits;
__traits::construct(__alloc, __dest, std::move(*__orig));
__traits::destroy(__alloc, std::__addressof(*__orig));
}
// This class may be specialized for specific types.
template<typename _Tp>
struct __is_trivially_relocatable
: is_trivial<_Tp> { };
template <typename _Tp, typename _Up>
inline __enable_if_t<std::__is_trivially_relocatable<_Tp>::value, _Tp*>
__relocate_a_1(_Tp* __first, _Tp* __last,
_Tp* __result, allocator<_Up>& __alloc)
{
ptrdiff_t __count = __last - __first;
__builtin_memmove(__result, __first, __count * sizeof(_Tp));
return __result + __count;
}
template <typename _InputIterator, typename _ForwardIterator,
typename _Allocator>
inline _ForwardIterator
__relocate_a_1(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result, _Allocator& __alloc)
{
typedef typename iterator_traits<_InputIterator>::value_type
_ValueType;
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType2;
static_assert(std::is_same<_ValueType, _ValueType2>::value);
static_assert(noexcept(std::__relocate_object_a(std::addressof(*__result),
std::addressof(*__first),
__alloc)));
_ForwardIterator __cur = __result;
for (; __first != __last; ++__first, (void)++__cur)
std::__relocate_object_a(std::__addressof(*__cur),
std::__addressof(*__first), __alloc);
return __cur;
}
template <typename _InputIterator, typename _ForwardIterator,
typename _Allocator>
inline _ForwardIterator
__relocate_a(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result, _Allocator& __alloc)
{
return __relocate_a_1(std::__niter_base(__first),
std::__niter_base(__last),
std::__niter_base(__result), __alloc);
}
#endif
_GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION
} // namespace } // namespace
......
...@@ -421,6 +421,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -421,6 +421,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef ptrdiff_t difference_type; typedef ptrdiff_t difference_type;
typedef _Alloc allocator_type; typedef _Alloc allocator_type;
private:
#if __cplusplus >= 201103L
static constexpr bool __use_relocate =
noexcept(std::__relocate_object_a(
std::addressof(*std::declval<pointer>()),
std::addressof(*std::declval<pointer>()),
std::declval<_Tp_alloc_type&>()));
#endif
protected: protected:
using _Base::_M_allocate; using _Base::_M_allocate;
using _Base::_M_deallocate; using _Base::_M_deallocate;
......
...@@ -71,12 +71,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -71,12 +71,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (this->capacity() < __n) if (this->capacity() < __n)
{ {
const size_type __old_size = size(); const size_type __old_size = size();
pointer __tmp = _M_allocate_and_copy(__n, pointer __tmp;
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start), #if __cplusplus >= 201103L
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish)); if constexpr (__use_relocate)
{
__tmp = this->_M_allocate(__n);
std::__relocate_a(this->_M_impl._M_start,
this->_M_impl._M_finish,
__tmp, _M_get_Tp_allocator());
}
else
#endif
{
__tmp = _M_allocate_and_copy(__n,
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start),
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish));
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator());
}
_GLIBCXX_ASAN_ANNOTATE_REINIT; _GLIBCXX_ASAN_ANNOTATE_REINIT;
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start, _M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage this->_M_impl._M_end_of_storage
- this->_M_impl._M_start); - this->_M_impl._M_start);
...@@ -295,9 +308,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -295,9 +308,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ {
_S_check_init_len(__len, _M_get_Tp_allocator()); _S_check_init_len(__len, _M_get_Tp_allocator());
pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
_GLIBCXX_ASAN_ANNOTATE_REINIT;
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator()); _M_get_Tp_allocator());
_GLIBCXX_ASAN_ANNOTATE_REINIT;
_M_deallocate(this->_M_impl._M_start, _M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage this->_M_impl._M_end_of_storage
- this->_M_impl._M_start); - this->_M_impl._M_start);
...@@ -443,17 +456,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -443,17 +456,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#endif #endif
__new_finish = pointer(); __new_finish = pointer();
__new_finish #if __cplusplus >= 201103L
= std::__uninitialized_move_if_noexcept_a if constexpr (__use_relocate)
(__old_start, __position.base(), {
__new_start, _M_get_Tp_allocator()); __new_finish
= std::__relocate_a
(__old_start, __position.base(),
__new_start, _M_get_Tp_allocator());
++__new_finish;
__new_finish
= std::__relocate_a
(__position.base(), __old_finish,
__new_finish, _M_get_Tp_allocator());
}
else
#endif
{
__new_finish
= std::__uninitialized_move_if_noexcept_a
(__old_start, __position.base(),
__new_start, _M_get_Tp_allocator());
++__new_finish; ++__new_finish;
__new_finish __new_finish
= std::__uninitialized_move_if_noexcept_a = std::__uninitialized_move_if_noexcept_a
(__position.base(), __old_finish, (__position.base(), __old_finish,
__new_finish, _M_get_Tp_allocator()); __new_finish, _M_get_Tp_allocator());
}
} }
__catch(...) __catch(...)
{ {
...@@ -465,8 +497,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -465,8 +497,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_deallocate(__new_start, __len); _M_deallocate(__new_start, __len);
__throw_exception_again; __throw_exception_again;
} }
#if __cplusplus >= 201103L
if constexpr (!__use_relocate)
#endif
std::_Destroy(__old_start, __old_finish, _M_get_Tp_allocator());
_GLIBCXX_ASAN_ANNOTATE_REINIT; _GLIBCXX_ASAN_ANNOTATE_REINIT;
std::_Destroy(__old_start, __old_finish, _M_get_Tp_allocator());
_M_deallocate(__old_start, _M_deallocate(__old_start,
this->_M_impl._M_end_of_storage - __old_start); this->_M_impl._M_end_of_storage - __old_start);
this->_M_impl._M_start = __new_start; this->_M_impl._M_start = __new_start;
...@@ -562,9 +597,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -562,9 +597,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_deallocate(__new_start, __len); _M_deallocate(__new_start, __len);
__throw_exception_again; __throw_exception_again;
} }
_GLIBCXX_ASAN_ANNOTATE_REINIT;
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator()); _M_get_Tp_allocator());
_GLIBCXX_ASAN_ANNOTATE_REINIT;
_M_deallocate(this->_M_impl._M_start, _M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage this->_M_impl._M_end_of_storage
- this->_M_impl._M_start); - this->_M_impl._M_start);
...@@ -603,27 +638,48 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -603,27 +638,48 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const size_type __len = const size_type __len =
_M_check_len(__n, "vector::_M_default_append"); _M_check_len(__n, "vector::_M_default_append");
pointer __new_start(this->_M_allocate(__len)); pointer __new_start(this->_M_allocate(__len));
pointer __destroy_from = pointer(); #if __cplusplus >= 201103L
__try if constexpr (__use_relocate)
{ {
std::__uninitialized_default_n_a(__new_start + __size, __try
__n, _M_get_Tp_allocator()); {
__destroy_from = __new_start + __size; std::__uninitialized_default_n_a(__new_start + __size,
std::__uninitialized_move_if_noexcept_a( __n, _M_get_Tp_allocator());
this->_M_impl._M_start, this->_M_impl._M_finish, }
__new_start, _M_get_Tp_allocator()); __catch(...)
{
_M_deallocate(__new_start, __len);
__throw_exception_again;
}
std::__relocate_a(this->_M_impl._M_start,
this->_M_impl._M_finish,
__new_start, _M_get_Tp_allocator());
} }
__catch(...) else
#endif
{ {
if (__destroy_from) pointer __destroy_from = pointer();
std::_Destroy(__destroy_from, __destroy_from + __n, __try
_M_get_Tp_allocator()); {
_M_deallocate(__new_start, __len); std::__uninitialized_default_n_a(__new_start + __size,
__throw_exception_again; __n, _M_get_Tp_allocator());
__destroy_from = __new_start + __size;
std::__uninitialized_move_if_noexcept_a(
this->_M_impl._M_start, this->_M_impl._M_finish,
__new_start, _M_get_Tp_allocator());
}
__catch(...)
{
if (__destroy_from)
std::_Destroy(__destroy_from, __destroy_from + __n,
_M_get_Tp_allocator());
_M_deallocate(__new_start, __len);
__throw_exception_again;
}
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator());
} }
_GLIBCXX_ASAN_ANNOTATE_REINIT; _GLIBCXX_ASAN_ANNOTATE_REINIT;
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start, _M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage this->_M_impl._M_end_of_storage
- this->_M_impl._M_start); - this->_M_impl._M_start);
...@@ -742,9 +798,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -742,9 +798,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_deallocate(__new_start, __len); _M_deallocate(__new_start, __len);
__throw_exception_again; __throw_exception_again;
} }
_GLIBCXX_ASAN_ANNOTATE_REINIT;
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator()); _M_get_Tp_allocator());
_GLIBCXX_ASAN_ANNOTATE_REINIT;
_M_deallocate(this->_M_impl._M_start, _M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage this->_M_impl._M_end_of_storage
- this->_M_impl._M_start); - this->_M_impl._M_start);
......
...@@ -80,6 +80,8 @@ template<typename _Alloc, typename = typename _Alloc::value_type> ...@@ -80,6 +80,8 @@ template<typename _Alloc, typename = typename _Alloc::value_type>
template<typename _Ptr, typename... _Args> template<typename _Ptr, typename... _Args>
static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type
construct(_Alloc& __a, _Ptr __p, _Args&&... __args) construct(_Alloc& __a, _Ptr __p, _Args&&... __args)
noexcept(noexcept(_Base_type::construct(__a, std::__to_address(__p),
std::forward<_Args>(__args)...)))
{ {
_Base_type::construct(__a, std::__to_address(__p), _Base_type::construct(__a, std::__to_address(__p),
std::forward<_Args>(__args)...); std::forward<_Args>(__args)...);
...@@ -89,6 +91,7 @@ template<typename _Alloc, typename = typename _Alloc::value_type> ...@@ -89,6 +91,7 @@ template<typename _Alloc, typename = typename _Alloc::value_type>
template<typename _Ptr> template<typename _Ptr>
static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type
destroy(_Alloc& __a, _Ptr __p) destroy(_Alloc& __a, _Ptr __p)
noexcept(noexcept(_Base_type::destroy(__a, std::__to_address(__p))))
{ _Base_type::destroy(__a, std::__to_address(__p)); } { _Base_type::destroy(__a, std::__to_address(__p)); }
static _Alloc _S_select_on_copy(const _Alloc& __a) static _Alloc _S_select_on_copy(const _Alloc& __a)
......
...@@ -151,11 +151,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -151,11 +151,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Up, typename... _Args> template<typename _Up, typename... _Args>
void void
construct(_Up* __p, _Args&&... __args) construct(_Up* __p, _Args&&... __args)
noexcept(noexcept(::new((void *)__p)
_Up(std::forward<_Args>(__args)...)))
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
template<typename _Up> template<typename _Up>
void void
destroy(_Up* __p) { __p->~_Up(); } destroy(_Up* __p)
noexcept(noexcept(__p->~_Up()))
{ __p->~_Up(); }
#else #else
// _GLIBCXX_RESOLVE_LIB_DEFECTS // _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_] allocator::construct // 402. wrong new expression in [some_] allocator::construct
......
...@@ -142,11 +142,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -142,11 +142,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Up, typename... _Args> template<typename _Up, typename... _Args>
void void
construct(_Up* __p, _Args&&... __args) construct(_Up* __p, _Args&&... __args)
noexcept(noexcept(::new((void *)__p)
_Up(std::forward<_Args>(__args)...)))
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
template<typename _Up> template<typename _Up>
void void
destroy(_Up* __p) { __p->~_Up(); } destroy(_Up* __p)
noexcept(noexcept( __p->~_Up()))
{ __p->~_Up(); }
#else #else
// _GLIBCXX_RESOLVE_LIB_DEFECTS // _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_] allocator::construct // 402. wrong new expression in [some_] allocator::construct
......
...@@ -24,11 +24,11 @@ ...@@ -24,11 +24,11 @@
// libstdc++/49836 // libstdc++/49836
void test01() void test01()
{ {
using __gnu_test::CopyConsOnlyType; using __gnu_test::assign::DelAnyAssign;
using __gnu_test::MoveConsOnlyType; using __gnu_test::MoveConsOnlyType;
std::vector<CopyConsOnlyType> v1; std::vector<DelAnyAssign> v1;
CopyConsOnlyType t1(1); DelAnyAssign t1;
v1.push_back(t1); v1.push_back(t1);
v1.push_back(t1); v1.push_back(t1);
v1.push_back(t1); v1.push_back(t1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment