From patchwork Mon May 10 20:22:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1476707 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=PD5UHBZ8; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FfCCv3Hrkz9sX5 for ; Tue, 11 May 2021 06:22:49 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2A980385740D; Mon, 10 May 2021 20:22:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2A980385740D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1620678167; bh=AHCcKjFl/ztndPtAqy+ZTfqgGgvW36nro4Uc5ql8E6c=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=PD5UHBZ8/4TK+yxlvJuEXQwfEGyVhq6FT/8mu7W4dDPj3drFEoIFvI4NBHt3r4T4H I/9d1y9D3ImZYBw5TRwyVtS6vQ9VDqSEnurHuq+idWQAdnlbbLJAvn+Nz2mmR90tZ9 OqoYkVW0BdRZybAqO0I0Xw8cgEeb0wldaudIOBh4= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id 428693861034 for ; Mon, 10 May 2021 20:22:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 428693861034 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-397-EQWf9LjPONWw_vCaKJHSbg-1; Mon, 10 May 2021 16:22:40 -0400 X-MC-Unique: EQWf9LjPONWw_vCaKJHSbg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8794A107ACC7; Mon, 10 May 2021 20:22:39 +0000 (UTC) Received: from localhost (unknown [10.33.36.164]) by smtp.corp.redhat.com (Postfix) with ESMTP id 19FFE1037F2F; Mon, 10 May 2021 20:22:38 +0000 (UTC) Date: Mon, 10 May 2021 21:22:38 +0100 To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Implement proposed resolution to LWG 3548 Message-ID: MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-14.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jonathan Wakely via Gcc-patches From: Jonathan Wakely Reply-To: Jonathan Wakely Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" 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. Tested powerpc64le-linux. Committed to trunk. commit 5edc0c15f1667cc2a5deb664b25c007b35d259f6 Author: Jonathan Wakely Date: Mon May 10 20:46:38 2021 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. diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 71099afbf7a..eb9ad23ba1e 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -684,8 +684,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; } @@ -1070,9 +1073,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 f4cf3ddda2e..d7ca51a4aa6 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(); }