diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -652,7 +652,8 @@ template ::value && - is_convertible::pointer, element_type*>::value + is_convertible::pointer, element_type*>::value && + is_move_constructible<_Dp>::value > > _LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) @@ -666,7 +667,7 @@ { typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; typedef __shared_ptr_pointer::pointer, _Dp, _AllocT > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT()); + __cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT()); __enable_weak_this(__r.get(), __r.get()); } __r.release(); diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp @@ -82,6 +82,14 @@ } }; +template +struct MoveOnlyDeleter { + MoveOnlyDeleter() {} + MoveOnlyDeleter(MoveOnlyDeleter&&) {} + MoveOnlyDeleter(MoveOnlyDeleter&) = delete; + void operator()(T* p) const { delete p; } +}; + int main(int, char**) { { @@ -219,5 +227,10 @@ } #endif // TEST_STD_VER >= 14 + { // LWG 3548 + std::unique_ptr > u; + std::shared_ptr s(std::move(u)); + } + return 0; }