diff options
author | Marshall Clow <mclow.lists@gmail.com> | 2016-07-11 21:38:08 +0000 |
---|---|---|
committer | Marshall Clow <mclow.lists@gmail.com> | 2016-07-11 21:38:08 +0000 |
commit | dc3eb83d08d63d41824d87e64c10021faee44c6e (patch) | |
tree | 817e696bbdaaadc91e760d0e08b2fd7f8f554ae2 /libcxx/include | |
parent | 83a25792c5c2fc658736af63b7fc51172642be01 (diff) | |
download | bcm5719-llvm-dc3eb83d08d63d41824d87e64c10021faee44c6e.tar.gz bcm5719-llvm-dc3eb83d08d63d41824d87e64c10021faee44c6e.zip |
Always use the allocator to construct/destruct elements of a deque/vector. Fixes PR#28412. Thanks to Jonathan Wakely for the report.
llvm-svn: 275105
Diffstat (limited to 'libcxx/include')
-rw-r--r-- | libcxx/include/deque | 8 | ||||
-rw-r--r-- | libcxx/include/memory | 20 | ||||
-rw-r--r-- | libcxx/include/vector | 4 |
3 files changed, 26 insertions, 6 deletions
diff --git a/libcxx/include/deque b/libcxx/include/deque index c6fbd512a1c..57650427645 100644 --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -2026,7 +2026,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) } else { - value_type __tmp(_VSTD::forward<_Args>(__args)...); + __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...); iterator __b = __base::begin(); iterator __bm1 = _VSTD::prev(__b); __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); @@ -2034,7 +2034,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) ++__base::size(); if (__pos > 1) __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b); - *__b = _VSTD::move(__tmp); + *__b = _VSTD::move(__tmp.get()); } } else @@ -2050,14 +2050,14 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) } else { - value_type __tmp(_VSTD::forward<_Args>(__args)...); + __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...); iterator __e = __base::end(); iterator __em1 = _VSTD::prev(__e); __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); ++__base::size(); if (__de > 1) __e = _VSTD::move_backward(__e - __de, __em1, __e); - *--__e = _VSTD::move(__tmp); + *--__e = _VSTD::move(__tmp.get()); } } return __base::begin() + __pos; diff --git a/libcxx/include/memory b/libcxx/include/memory index 50a1f00a5e5..7a3281e1793 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -5674,6 +5674,26 @@ struct __noexcept_move_assign_container : public integral_constant<bool, #endif > {}; + +#ifndef _LIBCPP_HAS_NO_VARIADICS +template <class _Tp, class _Alloc> +struct __temp_value { + typedef allocator_traits<_Alloc> _Traits; + + typename aligned_storage<sizeof(_Tp), alignof(_Tp)>::type __v; + _Alloc &__a; + + _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); } + _Tp & get() { return *__addr(); } + + template<class... _Args> + __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) + { _Traits::construct(__a, __addr(), _VSTD::forward<_Args>(__args)...); } + + ~__temp_value() { _Traits::destroy(__a, __addr()); } + }; +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_MEMORY diff --git a/libcxx/include/vector b/libcxx/include/vector index 81c514ee6b7..021bbfb6643 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -1812,9 +1812,9 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) } else { - value_type __tmp(_VSTD::forward<_Args>(__args)...); + __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...); __move_range(__p, this->__end_, __p + 1); - *__p = _VSTD::move(__tmp); + *__p = _VSTD::move(__tmp.get()); } __annotator.__done(); } |