[libcxx-commits] [libcxx] [libc++] Remove _LIBCPP_COMPRESSED_PAIR/TRIPLE from shared_ptr (PR #200401)
Nico Weber via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Sep 9 06:57:30 PDT 2026
================
@@ -128,79 +126,53 @@ class __shared_ptr_pointer : public __shared_weak_count {
struct __for_overwrite_tag {};
template <class _Tp, class _Alloc>
-struct __shared_ptr_emplace : __shared_weak_count {
- using __value_type _LIBCPP_NODEBUG = __remove_cv_t<_Tp>;
+struct _LIBCPP_HIDE_STRUCT_FROM_ABI __shared_ptr_emplace : __shared_weak_count {
+ using __alloc_t _LIBCPP_NODEBUG = __allocator_traits_rebind_t<_Alloc, __shared_ptr_emplace>;
+ using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<__alloc_t>;
+ using __value_type _LIBCPP_NODEBUG = __remove_cv_t<_Tp>;
- template <class... _Args,
- class _Allocator = _Alloc,
- __enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&...) : __storage_(std::move(__a)) {
- static_assert(
- sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");
- ::new (static_cast<void*>(__get_elem())) __value_type;
+ template <class... _Args>
+ _LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&... __args) : __alloc_(std::move(__a)) {
+ __alloc_traits::construct(__alloc_, __get_elem(), std::forward<_Args>(__args)...);
}
- template <class... _Args,
- class _Allocator = _Alloc,
- __enable_if_t<!is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&... __args) : __storage_(std::move(__a)) {
- using _TpAlloc = typename __allocator_traits_rebind<_Alloc, __value_type>::type;
- _TpAlloc __tmp(*__get_alloc());
- allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), std::forward<_Args>(__args)...);
- }
-
- _LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
-
- _LIBCPP_HIDE_FROM_ABI __value_type* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
+ _LIBCPP_HIDE_FROM_ABI __value_type* __get_elem() _NOEXCEPT { return reinterpret_cast<__value_type*>(__buffer_); }
private:
- template <class _Allocator = _Alloc,
- __enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI void __on_zero_shared_impl() _NOEXCEPT {
- __get_elem()->~__value_type();
- }
-
- template <class _Allocator = _Alloc,
- __enable_if_t<!is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI void __on_zero_shared_impl() _NOEXCEPT {
- using _TpAlloc = typename __allocator_traits_rebind<_Allocator, __remove_cv_t<_Tp> >::type;
- _TpAlloc __tmp(*__get_alloc());
- allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
+ __alloc_traits::destroy(__alloc_, __get_elem());
}
- _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { __on_zero_shared_impl(); }
-
_LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
- using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
- using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;
- _ControlBlockAlloc __tmp(*__get_alloc());
- __storage_.~_Storage();
- allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1);
+ __alloc_t __tmp(__alloc_);
+ __alloc_.~__alloc_t();
+ __alloc_traits::deallocate(__tmp, pointer_traits<typename __alloc_traits::pointer>::pointer_to(*this), 1);
}
- // TODO: It should be possible to refactor this to remove `_Storage` entirely.
- // This class implements the control block for non-array shared pointers created
- // through `std::allocate_shared` and `std::make_shared`.
- struct _Storage {
- struct _Data {
- _LIBCPP_COMPRESSED_PAIR(_Alloc, __alloc_, __value_type, __elem_);
- };
+ _LIBCPP_NO_UNIQUE_ADDRESS __alloc_t __alloc_;
+ _ALIGNAS_TYPE(__value_type) char __buffer_[sizeof(__value_type)];
+};
- _ALIGNAS_TYPE(_Data) char __buffer_[sizeof(_Data)];
+template <class _Tp, class _Alloc>
+struct _LIBCPP_HIDE_STRUCT_FROM_ABI __shared_ptr_emplace_for_overwrite : __shared_weak_count {
+ using __alloc_t _LIBCPP_NODEBUG = __allocator_traits_rebind_t<_Alloc, __shared_ptr_emplace_for_overwrite>;
+ using __value_type _LIBCPP_NODEBUG = __remove_cv_t<_Tp>;
- _LIBCPP_HIDE_FROM_ABI explicit _Storage(_Alloc&& __a) { ::new ((void*)__get_alloc()) _Alloc(std::move(__a)); }
- _LIBCPP_HIDE_FROM_ABI ~_Storage() { __get_alloc()->~_Alloc(); }
+ explicit __shared_ptr_emplace_for_overwrite(_Alloc __a) : __alloc_(std::move(__a)) {}
- _LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT {
- return std::addressof(reinterpret_cast<_Data*>(__buffer_)->__alloc_);
- }
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { __value_.~__value_type(); }
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
+ __alloc_t __tmp(__alloc_);
+ __alloc_.~__alloc_t();
+ using __alloc_traits = allocator_traits<__alloc_t>;
+ __alloc_traits::deallocate(__tmp, pointer_traits<typename __alloc_traits::pointer>::pointer_to(*this), 1);
+ }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __value_type* __get_elem() _NOEXCEPT {
----------------
nico wrote:
FWIW the _LIBCPP_NO_CFI removal here required us to add a CFI suppression for this function downstream. Consider re-adding it.
https://github.com/llvm/llvm-project/pull/200401
More information about the libcxx-commits
mailing list