From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 586113AA7C88; Fri, 18 Jun 2021 11:50:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 586113AA7C88 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r10-9933] libstdc++: Implement proposed resolution to LWG 3548 X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/releases/gcc-10 X-Git-Oldrev: b7cf6b97fc3f6c02a5d0114fed14f40b08ab3ad8 X-Git-Newrev: 15d6f574615b78c5e783ea51924f6e452a3ff45b Message-Id: <20210618115028.586113AA7C88@sourceware.org> Date: Fri, 18 Jun 2021 11:50:28 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Jun 2021 11:50:28 -0000 https://gcc.gnu.org/g:15d6f574615b78c5e783ea51924f6e452a3ff45b commit r10-9933-g15d6f574615b78c5e783ea51924f6e452a3ff45b Author: Jonathan Wakely Date: Mon May 10 20:46:38 2021 +0100 libstdc++: Implement proposed resolution to LWG 3548 This has been tentatively approved by LWG. The deleter from a unique_ptr can be moved into the shared_ptr (at least, since LWG 2802). This uses std::forward<_Del>(__r.get_deleter()) not std::move(__r.get_deleter()) because we don't want to convert the deleter to an rvalue when _Del is an lvalue reference type. This also adds a missing is_move_constructible_v constraint to the shared_ptr(unique_ptr&&) constructor, which is inherited from the shared_ptr(Y*, D) constructor due to the use of "equivalent to" in the specified effects. libstdc++-v3/ChangeLog: * include/bits/shared_ptr_base.h (__shared_count(unique_ptr&&)): Initialize a non-reference deleter from an rvalue, as per LWG 3548. (__shared_ptr::_UniqCompatible): Add missing constraint. * testsuite/20_util/shared_ptr/cons/lwg3548.cc: New test. * testsuite/20_util/shared_ptr/cons/unique_ptr_deleter.cc: Check constraints. (cherry picked from commit 5edc0c15f1667cc2a5deb664b25c007b35d259f6) Diff: --- libstdc++-v3/include/bits/shared_ptr_base.h | 13 +++++++++---- .../testsuite/20_util/shared_ptr/cons/lwg3548.cc | 16 ++++++++++++++++ .../20_util/shared_ptr/cons/unique_ptr_deleter.cc | 17 ++++++++++++++++- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index f0232c36be9..219007b2c07 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -716,8 +716,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using _Alloc_traits = allocator_traits<_Alloc>; _Alloc __a; _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3548. shared_ptr construction from unique_ptr should move + // (not copy) the deleter _Alloc_traits::construct(__a, __mem, __r.release(), - __r.get_deleter()); // non-throwing + std::forward<_Del>(__r.get_deleter())); _M_pi = __mem; } @@ -1104,9 +1107,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Constraint for construction from unique_ptr: template::pointer> - using _UniqCompatible = typename enable_if<__and_< - __sp_compatible_with<_Yp*, _Tp*>, is_convertible<_Ptr, element_type*> - >::value, _Res>::type; + using _UniqCompatible = __enable_if_t<__and_< + __sp_compatible_with<_Yp*, _Tp*>, + is_convertible<_Ptr, element_type*>, + is_move_constructible<_Del> + >::value, _Res>; // Constraint for assignment from unique_ptr: template diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/lwg3548.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/lwg3548.cc new file mode 100644 index 00000000000..d6ec7b1d057 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/lwg3548.cc @@ -0,0 +1,16 @@ +// { dg-do compile { target c++11 } } + +#include + +// LWG 3548 +// shared_ptr construction from unique_ptr should move (not copy) the deleter + +struct D +{ + D() { } + D(D&&) { } + void operator()(int* p) const { delete p; } +}; + +std::unique_ptr u; +std::shared_ptr s1(std::move(u)); diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_deleter.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_deleter.cc index 3205cc37f1f..506e1823c8f 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_deleter.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_deleter.cc @@ -58,10 +58,25 @@ test02() VERIFY( D::count == 0 ); // LWG 2415 } +void +test03() +{ + struct D + { + D() = default; + D(const D&) = delete; // not copyable or movable + void operator()(int* p) const { delete p; } + }; + + using namespace std; + static_assert( ! is_constructible, unique_ptr>(), + "Constraints: is_move_constructible_v is true" ); +} + int main() { test01(); test02(); - return 0; + test03(); }