diff --git a/libcxx/include/vector b/libcxx/include/vector --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -839,15 +839,15 @@ #ifndef _LIBCPP_CXX03_LANG template _LIBCPP_INLINE_VISIBILITY - inline void __push_back_slow_path(_Up&& __x); + inline pointer __push_back_slow_path(_Up&& __x); template _LIBCPP_INLINE_VISIBILITY - inline void __emplace_back_slow_path(_Args&&... __args); + inline pointer __emplace_back_slow_path(_Args&&... __args); #else template _LIBCPP_INLINE_VISIBILITY - inline void __push_back_slow_path(_Up& __x); + inline pointer __push_back_slow_path(_Up& __x); #endif // The following functions are no-ops outside of AddressSanitizer mode. @@ -919,6 +919,39 @@ _ConstructTransaction& operator=(_ConstructTransaction const&) = delete; }; +#if defined(_LIBCPP_HAS_NO_ASAN) + struct _AsanTransaction { + explicit _AsanTransaction(vector&, size_type) {} + void __commit(size_type) {} + }; +#elif defined(_LIBCPP_NO_EXCEPTIONS) + struct _AsanTransaction { + explicit _AsanTransaction(vector &, size_type __n) { + __v_.__annotate_increase(__n); + } + void __commit(size_type) {} + }; +#else // _LIBCPP_NO_EXCEPTIONS + struct _AsanTransaction { + _AsanTransaction(vector& __v, size_type __n) : __v_(__v), __n(__n) { + __v_.__annotate_increase(__n); + } + ~_AsanTransaction() { __v_.__annotate_shrink(__n_); } + void __commit(size_type __n) { __n_ -= __n; } + vector& __v_; + size_t __n_; + }; +#endif // _LIBCPP_NO_EXCEPTIONS + + template + _LIBCPP_INLINE_VISIBILITY void __construct_one_at(pointer __pos, + _Args&&... __args) { + _AsanTransaction tx(*this, 1); + __alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__pos), + _VSTD::forward<_Args>(__args)...); + tx.__commit(1); + } + template _LIBCPP_INLINE_VISIBILITY void __construct_one_at_end(_Args&& ...__args) { @@ -1614,7 +1647,7 @@ template template -void +typename vector<_Tp, _Allocator>::pointer #ifndef _LIBCPP_CXX03_LANG vector<_Tp, _Allocator>::__push_back_slow_path(_Up&& __x) #else @@ -1627,6 +1660,7 @@ __alloc_traits::construct(__a, _VSTD::__to_address(__v.__end_), _VSTD::forward<_Up>(__x)); __v.__end_++; __swap_out_circular_buffer(__v); + return this->__end_; } template @@ -1634,12 +1668,15 @@ void vector<_Tp, _Allocator>::push_back(const_reference __x) { - if (this->__end_ != this->__end_cap()) + pointer __end = this->__end_; + if (__end != this->__end_cap()) { - __construct_one_at_end(__x); + __construct_one_at(__end, __x); } - else - __push_back_slow_path(__x); + else { + __end = __push_back_slow_path(__x) - 1; + } + this->__end_ = __end + 1; } #ifndef _LIBCPP_CXX03_LANG @@ -1649,17 +1686,20 @@ void vector<_Tp, _Allocator>::push_back(value_type&& __x) { - if (this->__end_ < this->__end_cap()) + pointer __end = this->__end_; + if (__end != this->__end_cap()) { - __construct_one_at_end(_VSTD::move(__x)); + __construct_one_at(__end, _VSTD::move(__x)); } - else - __push_back_slow_path(_VSTD::move(__x)); + else { + __end = __push_back_slow_path(std::move(__x)) - 1; + } + this->__end_ = __end + 1; } template template -void +typename vector<_Tp, _Allocator>::pointer vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) { allocator_type& __a = this->__alloc(); @@ -1668,6 +1708,7 @@ __alloc_traits::construct(__a, _VSTD::__to_address(__v.__end_), _VSTD::forward<_Args>(__args)...); __v.__end_++; __swap_out_circular_buffer(__v); + return this->__end_; } template @@ -1680,14 +1721,16 @@ #endif vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) { - if (this->__end_ < this->__end_cap()) + pointer __pos = this->__end_; + if (__pos < this->__end_cap()) { - __construct_one_at_end(_VSTD::forward<_Args>(__args)...); + __construct_one_at(__pos, _VSTD::forward<_Args>(__args)...); + } else { + __pos = __emplace_back_slow_path(_VSTD::forward<_Args>(__args)...) - 1; } - else - __emplace_back_slow_path(_VSTD::forward<_Args>(__args)...); + this->__end_ = __pos + 1; #if _LIBCPP_STD_VER > 14 - return this->back(); + return *__pos; #endif }