Index: include/memory =================================================================== --- include/memory +++ include/memory @@ -3761,12 +3761,26 @@ typename enable_if::value, __nat>::type = __nat()); template shared_ptr(_Yp* __p, _Dp __d, - typename enable_if::value, __nat>::type = __nat()); + typename enable_if< + is_convertible<_Yp*, element_type*>::value && + _VSTD::is_move_constructible<_Dp>::value, + __nat>::type = __nat()); template shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, - typename enable_if::value, __nat>::type = __nat()); - template shared_ptr(nullptr_t __p, _Dp __d); - template shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a); + typename enable_if< + is_convertible<_Yp*, element_type*>::value && + _VSTD::is_move_constructible<_Dp>::value, + __nat>::type = __nat()); + template shared_ptr(nullptr_t __p, _Dp __d, + typename enable_if< + _VSTD::is_move_constructible<_Dp>::value, + __nat + >::type = __nat()); + template shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a, + typename enable_if< + _VSTD::is_move_constructible<_Dp>::value, + __nat + >::type = __nat()); template _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr& __r) _NOEXCEPT; @@ -4042,7 +4056,7 @@ unique_ptr<_CT, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); ::new(static_cast(_VSTD::addressof(*__hold2.get()))) - _CT(__p, __d, __a); + _CT(__p, _VSTD::move(__d), __a); return _VSTD::addressof(*__hold2.release()); } catch (...) { @@ -4065,7 +4079,7 @@ unique_ptr<_CT, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); ::new(static_cast(_VSTD::addressof(*__hold2.get()))) - _CT(__p, __d, __a); + _CT(__p, _VSTD::move(__d), __a); return _VSTD::addressof(*__hold2.release()); } catch (...) { @@ -4103,34 +4117,42 @@ template template shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, - typename enable_if::value, __nat>::type) + typename enable_if< + is_convertible<_Yp*, element_type*>::value && + _VSTD::is_move_constructible<_Dp>::value, + __nat>::type) : __ptr_(__p), - __cntrl_(__allocate_shared(__p, __d)) + __cntrl_(__allocate_shared(__p, _VSTD::move(__d))) { __enable_weak_this(__p, __p); } template template -shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d) +shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, + typename enable_if<_VSTD::is_move_constructible<_Dp>::value, __nat>::type) : __ptr_(0), - __cntrl_(__allocate_shared(__p, __d)) {} + __cntrl_(__allocate_shared(__p, _VSTD::move(__d))) {} template template shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, - typename enable_if::value, __nat>::type) + typename enable_if< + is_convertible<_Yp*, element_type*>::value && + _VSTD::is_move_constructible<_Dp>::value, + __nat>::type) : __ptr_(__p), - __cntrl_(__allocate_shared(__p, __d, __a)) + __cntrl_(__allocate_shared(__p, _VSTD::move(__d), __a)) { __enable_weak_this(__p, __p); } template template -shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a) +shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a, + typename enable_if<_VSTD::is_move_constructible<_Dp>::value, __nat>::type) : __ptr_(0), - __cntrl_(__allocate_shared(__p, __d, __a)) {} + __cntrl_(__allocate_shared(__p, _VSTD::move(__d), __a)) {} template template Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.fail.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// shared_ptr + +// template shared_ptr(Y* p, D d); + +#include + +struct NotDeleter +{ + NotDeleter() = default; + NotDeleter(NotDeleter const&) = default; + NotDeleter(NotDeleter&&) = default; +}; + +template +struct NoMoveDeleter +{ + NoMoveDeleter() = default; + NoMoveDeleter(NoMoveDeleter const&) = default; + NoMoveDeleter(NoMoveDeleter&&) = delete; + + void operator()(T*) { } +}; + +int main(int, char**) +{ + { + int* ptr = new int; + + // expected-error@memory:* {{type 'NotDeleter' does not provide a call operator}} + std::shared_ptr bp0(ptr, NotDeleter()); // expected-error@memory:* {{type 'NotDeleter' does not provide a call operator}} + + std::shared_ptr bp1(ptr, NoMoveDeleter()); // expected-error {{no matching constructor for initialization of 'std::shared_ptr'}} + } + + return 0; +} Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp @@ -27,6 +27,18 @@ int A::count = 0; +template +struct MoveDeleter +{ + MoveDeleter() = delete; + MoveDeleter(MoveDeleter const&) = delete; + MoveDeleter(MoveDeleter&&) = default; + + explicit MoveDeleter(int) {} + + void operator()(T*) { } +}; + int main(int, char**) { { @@ -45,5 +57,10 @@ assert(test_deleter::count == 0); assert(test_deleter::dealloc_count == 1); + { + MoveDeleter d(0); + std::shared_ptr p(new int, std::move(d)); + } + return 0; } Index: www/cxx1z_status.html =================================================================== --- www/cxx1z_status.html +++ www/cxx1z_status.html @@ -458,7 +458,7 @@ 2795§[global.functions] provides incorrect example of ADL useKonaComplete 2796tuple should be a literal typeKonaComplete 2801Default-constructibility of unique_ptrKonaComplete - 2802shared_ptr constructor requirements for a deleterKona + 2802shared_ptr constructor requirements for a deleterKonaComplete 2804Unconditional constexpr default constructor for istream_iteratorKonaComplete 2806Base class of bad_optional_accessKonaComplete 2807std::invoke should use std::is_nothrow_callableKonaComplete @@ -480,7 +480,7 @@ 2872Add definition for direct-non-list-initializationKonaComplete 2873Add noexcept to several shared_ptr related functionsKonaComplete 2874Constructor shared_ptr::shared_ptr(Y*) should be constrainedKona - 2875shared_ptr::shared_ptr(Y*, D, […]) constructors should be constrainedKona + 2875shared_ptr::shared_ptr(Y*, D, […]) constructors should be constrainedKonaComplete 2876shared_ptr::shared_ptr(const weak_ptr<Y>&) constructor should be constrainedKona 2878Missing DefaultConstructible requirement for istream_iterator default constructorKonaComplete 2890The definition of 'object state' applies only to class typesKonaComplete