diff --git a/libcxx/docs/Cxx1zStatusIssuesStatus.csv b/libcxx/docs/Cxx1zStatusIssuesStatus.csv --- a/libcxx/docs/Cxx1zStatusIssuesStatus.csv +++ b/libcxx/docs/Cxx1zStatusIssuesStatus.csv @@ -278,7 +278,7 @@ "`2795 `__","|sect|\ [global.functions] provides incorrect example of ADL use","Kona","|Complete|","" "`2796 `__","tuple should be a literal type","Kona","|Complete|","" "`2801 `__","Default-constructibility of unique_ptr","Kona","|Complete|","" -"`2802 `__","shared_ptr constructor requirements for a deleter","Kona","","" +"`2802 `__","shared_ptr constructor requirements for a deleter","Kona","|Complete|","" "`2804 `__","Unconditional constexpr default constructor for istream_iterator","Kona","|Complete|","" "`2806 `__","Base class of bad_optional_access","Kona","|Complete|","" "`2807 `__","std::invoke should use ``std::is_nothrow_callable``\ ","Kona","|Complete|","" diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -2930,7 +2930,11 @@ #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 @@ #endif // _LIBCPP_NO_EXCEPTIONS typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT; typedef __shared_ptr_pointer _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 @@ 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 @@ 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 --- 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 @@ struct Base { }; struct Derived : Base { }; +template +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 @@ static_assert(!std::is_constructible, Base[4], test_deleter >::value, ""); } +#if TEST_STD_VER >= 11 + { + MoveDeleter d(0); + std::shared_ptr p0(new int, std::move(d)); + std::shared_ptr 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 --- 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 @@ struct Base { }; struct Derived : Base { }; +template +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 @@ assert(A::count == 0); assert(test_deleter::count == 0); assert(test_deleter::dealloc_count == 1); -#endif + + { + MoveDeleter d(0); + std::shared_ptr p2(new int, std::move(d), std::allocator()); + std::shared_ptr p3(nullptr, std::move(d), std::allocator()); + } +#endif // TEST_STD_VER >= 11 { // Make sure that we can construct a shared_ptr where the element type and pointer type