[libcxx-commits] [libcxx] 68e2231 - [libc++] Value-initialize unique_ptr's deleter_type

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Nov 24 14:31:38 PST 2021


Author: Johan Berg
Date: 2021-11-24T17:31:34-05:00
New Revision: 68e2231f8724eec26c9fcf5c5330fae897f9435f

URL: https://github.com/llvm/llvm-project/commit/68e2231f8724eec26c9fcf5c5330fae897f9435f
DIFF: https://github.com/llvm/llvm-project/commit/68e2231f8724eec26c9fcf5c5330fae897f9435f.diff

LOG: [libc++] Value-initialize unique_ptr's deleter_type

According to the C++ standard, the stored pointer and the stored deleter
should be value-initialized.

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

Added: 
    

Modified: 
    libcxx/include/__memory/unique_ptr.h
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
    libcxx/test/support/deleter_types.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 838960269c973..433120394269f 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -174,17 +174,17 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
   template <bool _Dummy = true,
             class = _EnableIfDeleterDefaultConstructible<_Dummy> >
   _LIBCPP_INLINE_VISIBILITY
-  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {}
 
   template <bool _Dummy = true,
             class = _EnableIfDeleterDefaultConstructible<_Dummy> >
   _LIBCPP_INLINE_VISIBILITY
-  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {}
 
   template <bool _Dummy = true,
             class = _EnableIfDeleterDefaultConstructible<_Dummy> >
   _LIBCPP_INLINE_VISIBILITY
-  explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {}
+  explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {}
 
   template <bool _Dummy = true,
             class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
@@ -226,7 +226,7 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
              typename enable_if<is_convertible<_Up*, _Tp*>::value &&
                                     is_same<_Dp, default_delete<_Tp> >::value,
                                 __nat>::type = __nat()) _NOEXCEPT
-      : __ptr_(__p.release(), __default_init_tag()) {}
+      : __ptr_(__p.release(), __value_init_tag()) {}
 #endif
 
   _LIBCPP_INLINE_VISIBILITY
@@ -397,19 +397,19 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp>
   template <bool _Dummy = true,
             class = _EnableIfDeleterDefaultConstructible<_Dummy> >
   _LIBCPP_INLINE_VISIBILITY
-  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {}
 
   template <bool _Dummy = true,
             class = _EnableIfDeleterDefaultConstructible<_Dummy> >
   _LIBCPP_INLINE_VISIBILITY
-  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {}
 
   template <class _Pp, bool _Dummy = true,
             class = _EnableIfDeleterDefaultConstructible<_Dummy>,
             class = _EnableIfPointerConvertible<_Pp> >
   _LIBCPP_INLINE_VISIBILITY
   explicit unique_ptr(_Pp __p) _NOEXCEPT
-      : __ptr_(__p, __default_init_tag()) {}
+      : __ptr_(__p, __value_init_tag()) {}
 
   template <class _Pp, bool _Dummy = true,
             class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
index 1bd53b9a9ca5e..e8b356b6b526e 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
@@ -84,6 +84,11 @@ void test_basic() {
     p.get_deleter().set_state(5);
     assert(p.get_deleter().state() == 5);
   }
+  {
+    std::unique_ptr<ElemType, DefaultCtorDeleter<ElemType> > p;
+    assert(p.get() == 0);
+    assert(p.get_deleter().state() == 0);
+  }
 }
 
 DEFINE_AND_RUN_IS_INCOMPLETE_TEST({

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
index 0d0670658e376..74f0c5708a3a4 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
@@ -53,6 +53,11 @@ void test_basic() {
     assert(p.get() == 0);
     assert(p.get_deleter().state() == 0);
   }
+  {
+    std::unique_ptr<VT, DefaultCtorDeleter<VT> > p(nullptr);
+    assert(p.get() == 0);
+    assert(p.get_deleter().state() == 0);
+  }
 }
 
 template <class VT>

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
index 4e35fc050055f..364dd3aa3adef 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
@@ -69,6 +69,14 @@ void test_pointer() {
     assert(s.get_deleter().state() == 0);
   }
   assert(A::count == 0);
+  {
+    A* p = newValue<ValueT>(expect_alive);
+    assert(A::count == expect_alive);
+    std::unique_ptr<ValueT, DefaultCtorDeleter<ValueT> > s(p);
+    assert(s.get() == p);
+    assert(s.get_deleter().state() == 0);
+  }
+  assert(A::count == 0);
 }
 
 void test_derived() {

diff  --git a/libcxx/test/support/deleter_types.h b/libcxx/test/support/deleter_types.h
index 56cf7e330f3ec..f8aafc12bfdaa 100644
--- a/libcxx/test/support/deleter_types.h
+++ b/libcxx/test/support/deleter_types.h
@@ -442,4 +442,24 @@ class PointerDeleter<T[], ID>
 
 #endif // TEST_STD_VER >= 11
 
+template <class T>
+class DefaultCtorDeleter
+{
+    int state_;
+
+public:
+    int state() const {return state_;}
+    void operator()(T* p) {delete p;}
+};
+
+template <class T>
+class DefaultCtorDeleter<T[]>
+{
+    int state_;
+
+public:
+    int state() const {return state_;}
+    void operator()(T* p) {delete [] p;}
+};
+
 #endif // SUPPORT_DELETER_TYPES_H


        


More information about the libcxx-commits mailing list