[libcxx-commits] [libcxx] 6a328c6 - [libc++] shared_ptr deleter requirements (LWG 2802).

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Feb 18 21:32:30 PST 2021


Author: zoecarver
Date: 2021-02-18T21:31:07-08:00
New Revision: 6a328c66d35c71d5e92be80659186de567b86e38

URL: https://github.com/llvm/llvm-project/commit/6a328c66d35c71d5e92be80659186de567b86e38
DIFF: https://github.com/llvm/llvm-project/commit/6a328c66d35c71d5e92be80659186de567b86e38.diff

LOG: [libc++] shared_ptr deleter requirements (LWG 2802).

This patch implements 2802. Requires _Deleter to have call operator and be move constructible. Based on D62233.

Refs PR37637.

Differential Revision: https://reviews.llvm.org/D62274

Added: 
    

Modified: 
    libcxx/docs/Cxx1zStatusIssuesStatus.csv
    libcxx/include/memory
    libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp
    libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Cxx1zStatusIssuesStatus.csv b/libcxx/docs/Cxx1zStatusIssuesStatus.csv
index 12a7a9906256..9d369f2f77fa 100644
--- a/libcxx/docs/Cxx1zStatusIssuesStatus.csv
+++ b/libcxx/docs/Cxx1zStatusIssuesStatus.csv
@@ -278,7 +278,7 @@
 "`2795 <https://wg21.link/LWG2795>`__","|sect|\ [global.functions] provides incorrect example of ADL use","Kona","|Complete|",""
 "`2796 <https://wg21.link/LWG2796>`__","tuple should be a literal type","Kona","|Complete|",""
 "`2801 <https://wg21.link/LWG2801>`__","Default-constructibility of unique_ptr","Kona","|Complete|",""
-"`2802 <https://wg21.link/LWG2802>`__","shared_ptr constructor requirements for a deleter","Kona","",""
+"`2802 <https://wg21.link/LWG2802>`__","shared_ptr constructor requirements for a deleter","Kona","|Complete|",""
 "`2804 <https://wg21.link/LWG2804>`__","Unconditional constexpr default constructor for istream_iterator","Kona","|Complete|",""
 "`2806 <https://wg21.link/LWG2806>`__","Base class of bad_optional_access","Kona","|Complete|",""
 "`2807 <https://wg21.link/LWG2807>`__","std::invoke should use ``std::is_nothrow_callable``\ ","Kona","|Complete|",""

diff  --git a/libcxx/include/memory b/libcxx/include/memory
index ade8349dd3f2..7ce5f345f92b 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -2930,7 +2930,11 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
 #endif  // _LIBCPP_NO_EXCEPTIONS
         typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
         typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
+#ifndef _LIBCPP_CXX03_LANG
+        __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
+#else
         __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
+#endif // not _LIBCPP_CXX03_LANG
         __enable_weak_this(__p, __p);
 #ifndef _LIBCPP_NO_EXCEPTIONS
     }
@@ -2953,7 +2957,11 @@ shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
 #endif  // _LIBCPP_NO_EXCEPTIONS
         typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
         typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
+#ifndef _LIBCPP_CXX03_LANG
+        __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
+#else
         __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
+#endif // not _LIBCPP_CXX03_LANG
 #ifndef _LIBCPP_NO_EXCEPTIONS
     }
     catch (...)
@@ -2979,7 +2987,12 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
         typedef __allocator_destructor<_A2> _D2;
         _A2 __a2(__a);
         unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
-        ::new ((void*)_VSTD::addressof(*__hold2.get())) _CntrlBlk(__p, __d, __a);
+        ::new ((void*)_VSTD::addressof(*__hold2.get()))
+#ifndef _LIBCPP_CXX03_LANG
+            _CntrlBlk(__p, _VSTD::move(__d), __a);
+#else
+            _CntrlBlk(__p, __d, __a);
+#endif // not _LIBCPP_CXX03_LANG
         __cntrl_ = _VSTD::addressof(*__hold2.release());
         __enable_weak_this(__p, __p);
 #ifndef _LIBCPP_NO_EXCEPTIONS
@@ -3006,7 +3019,12 @@ shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
         typedef __allocator_destructor<_A2> _D2;
         _A2 __a2(__a);
         unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
-        ::new ((void*)_VSTD::addressof(*__hold2.get())) _CntrlBlk(__p, __d, __a);
+        ::new ((void*)_VSTD::addressof(*__hold2.get()))
+#ifndef _LIBCPP_CXX03_LANG
+            _CntrlBlk(__p, _VSTD::move(__d), __a);
+#else
+            _CntrlBlk(__p, __d, __a);
+#endif // not _LIBCPP_CXX03_LANG
         __cntrl_ = _VSTD::addressof(*__hold2.release());
 #ifndef _LIBCPP_NO_EXCEPTIONS
     }

diff  --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp
index 58b1bb919dff..3e5add73a994 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp
@@ -31,6 +31,19 @@ int A::count = 0;
 struct Base { };
 struct Derived : Base { };
 
+template<class T>
+class MoveDeleter
+{
+    MoveDeleter();
+    MoveDeleter(MoveDeleter const&);
+public:
+    MoveDeleter(MoveDeleter&&) {};
+
+    explicit MoveDeleter(int) {}
+
+    void operator()(T *ptr) { delete ptr; }
+};
+
 int main(int, char**)
 {
     {
@@ -57,5 +70,13 @@ int main(int, char**)
         static_assert(!std::is_constructible<std::shared_ptr<Derived[4]>, Base[4], test_deleter<Derived[4]> >::value, "");
     }
 
+#if TEST_STD_VER >= 11
+    {
+        MoveDeleter<int> d(0);
+        std::shared_ptr<int> p0(new int, std::move(d));
+        std::shared_ptr<int> p1(nullptr, std::move(d));
+    }
+#endif // TEST_STD_VER >= 11
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
index 4d0a29212628..48b962bf7db6 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
@@ -31,6 +31,19 @@ int A::count = 0;
 struct Base { };
 struct Derived : Base { };
 
+template<class T>
+class MoveDeleter
+{
+    MoveDeleter();
+    MoveDeleter(MoveDeleter const&);
+public:
+    MoveDeleter(MoveDeleter&&) {};
+
+    explicit MoveDeleter(int) {}
+
+    void operator()(T *ptr) { delete ptr; }
+};
+
 int main(int, char**)
 {
     {
@@ -93,7 +106,13 @@ int main(int, char**)
     assert(A::count == 0);
     assert(test_deleter<A>::count == 0);
     assert(test_deleter<A>::dealloc_count == 1);
-#endif
+
+    {
+        MoveDeleter<int> d(0);
+        std::shared_ptr<int> p2(new int, std::move(d), std::allocator<int>());
+        std::shared_ptr<int> p3(nullptr, std::move(d), std::allocator<int>());
+    }
+#endif // TEST_STD_VER >= 11
 
     {
         // Make sure that we can construct a shared_ptr where the element type and pointer type


        


More information about the libcxx-commits mailing list