[libcxx-commits] [PATCH] D113612: [libc++] Value-initialize unique_ptr's deleter_type

Johan Berg via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Wed Nov 10 14:10:54 PST 2021


bergjohan created this revision.
bergjohan requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

According to the C++ standard, the stored pointer and the stored deleter
should be value-initialized in the default constructor, and the
constructor taking a nullptr.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D113612

Files:
  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/support/deleter_types.h


Index: libcxx/test/support/deleter_types.h
===================================================================
--- libcxx/test/support/deleter_types.h
+++ libcxx/test/support/deleter_types.h
@@ -442,4 +442,24 @@
 
 #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
Index: 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/nullptr.pass.cpp
+++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
@@ -53,6 +53,11 @@
     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>
Index: 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/default.pass.cpp
+++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
@@ -84,6 +84,11 @@
     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({
Index: libcxx/include/__memory/unique_ptr.h
===================================================================
--- libcxx/include/__memory/unique_ptr.h
+++ libcxx/include/__memory/unique_ptr.h
@@ -174,12 +174,12 @@
   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> >
@@ -397,12 +397,12 @@
   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>,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113612.386314.patch
Type: text/x-patch
Size: 3660 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20211110/6bd44847/attachment.bin>


More information about the libcxx-commits mailing list