[libcxx-commits] [PATCH] D81133: Use allocator_traits to consistently allocate/deallocate/construct/destroy objects in std::any

Marshall Clow via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jun 3 23:57:36 PDT 2020


mclow.lists created this revision.
mclow.lists added a reviewer: libc++.
mclow.lists added a project: libc++.
mclow.lists edited the summary of this revision.
mclow.lists added a reviewer: tkoeppe.

PR45099 <https://llvm.org/PR40599> notes (correctly) that we're inconsistent in memory allocation in `std::any`. We allocate memory with `std::allocator<T>::allocate`, construct with placement new, destroy by calling the destructor directly, and deallocate by calling `delete`.   Most of those are customizable by the user - but in different ways.

The standard is silent on how these things are to be accomplished.
This patch makes it so we use `allocator_traits<allocator<T>>` for all of these operations (allocate, construct, destruct, deallocate). This is, at least, consistent.


https://reviews.llvm.org/D81133

Files:
  libcxx/include/any


Index: libcxx/include/any
===================================================================
--- libcxx/include/any
+++ libcxx/include/any
@@ -82,7 +82,6 @@
 
 #include <experimental/__config>
 #include <memory>
-#include <new>
 #include <typeinfo>
 #include <type_traits>
 #include <cstdlib>
@@ -368,7 +367,11 @@
     template <class ..._Args>
     _LIBCPP_INLINE_VISIBILITY
     static _Tp& __create(any & __dest, _Args&&... __args) {
-        _Tp* __ret = ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...);
+        typedef allocator<_Tp> _Alloc;
+        typedef allocator_traits<_Alloc> _ATraits;
+        _Alloc __a;
+        _Tp * __ret = static_cast<_Tp*>(static_cast<void*>(&__dest.__s.__buf));
+        _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...);
         __dest.__h = &_SmallHandler::__handle;
         return *__ret;
     }
@@ -376,8 +379,11 @@
   private:
     _LIBCPP_INLINE_VISIBILITY
     static void __destroy(any & __this) {
-        _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
-        __value.~_Tp();
+        typedef allocator<_Tp> _Alloc;
+        typedef allocator_traits<_Alloc> _ATraits;
+        _Alloc __a;
+        _Tp * __p = static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
+        _ATraits::destroy(__a, __p);
         __this.__h = nullptr;
     }
 
@@ -445,10 +451,12 @@
     _LIBCPP_INLINE_VISIBILITY
     static _Tp& __create(any & __dest, _Args&&... __args) {
         typedef allocator<_Tp> _Alloc;
+        typedef allocator_traits<_Alloc> _ATraits;
         typedef __allocator_destructor<_Alloc> _Dp;
         _Alloc __a;
-        unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-        _Tp* __ret = ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...);
+        unique_ptr<_Tp, _Dp> __hold(_ATraits::allocate(__a, 1), _Dp(__a, 1));
+        _Tp * __ret = __hold.get();
+        _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...);
         __dest.__s.__ptr = __hold.release();
         __dest.__h = &_LargeHandler::__handle;
         return *__ret;
@@ -458,7 +466,12 @@
 
     _LIBCPP_INLINE_VISIBILITY
     static void __destroy(any & __this){
-        delete static_cast<_Tp*>(__this.__s.__ptr);
+        typedef allocator<_Tp> _Alloc;
+        typedef allocator_traits<_Alloc> _ATraits;
+        _Alloc __a;
+        _Tp * __p = static_cast<_Tp *>(__this.__s.__ptr);
+        _ATraits::destroy(__a, __p);
+        _ATraits::deallocate(__a, __p, 1);
         __this.__h = nullptr;
     }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D81133.268368.patch
Type: text/x-patch
Size: 2572 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20200604/30d871c2/attachment.bin>


More information about the libcxx-commits mailing list