Message ID | Y0cX0wQJBbmESbG1@redhat.com |
---|---|
State | New, archived |
Headers |
Return-Path: <gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp2774118wrs; Wed, 12 Oct 2022 12:39:48 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6A2AEDteNCxcv3O6sRIKCcP2EX+a8lPgZtgqoly9gc+TdN+FOiHg5jdbOAcyhyUjNjrwDu X-Received: by 2002:a05:6402:1587:b0:458:fbea:436c with SMTP id c7-20020a056402158700b00458fbea436cmr28811214edv.407.1665603588438; Wed, 12 Oct 2022 12:39:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665603588; cv=none; d=google.com; s=arc-20160816; b=cnHjVxrH4AuEu1Db8zJ64MzTC3+8REaXr2j+nuQDoGcKWRjU/7W7wLmiQ/522Zl7ao RED1qscvVjnPIv/DCJ5fKb1WwtQ0TTwJgOhwwwDPfFcXhrMrFiPjQe4tojeNBXTORpQd znsT2+mxVMKrrwefOMf38Eq+haD2VFZQ2jWc3VKmWrcgl1IqC4Ax2uirK9lhBOjypk9k PLeqIgfGHRF33KrafENFuBhPB9phe7pxzjb5LnbYXRfKmQsjS6PLw+OIcPyDHdGDPPir 7J6Y7BK2WYtt5ferxXuN4cMSmDIiIG6hmixLdCChJstWIm3DEp52DL7ritbVut6t1w3c uWpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :content-disposition:user-agent:mime-version:message-id:subject:to :date:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=TGIF4gKIVuBMTDYkFOm5NrKTsQojOXfWhnvxrjSsTug=; b=XCmC401cKooeOcfi5v/Wy8S39exus43WglYe4bx8HlyO+bXqJWXQNLvbmZkUWRy2F+ c2cCIn+j4dM7V6ZkWNnGbNbOZ1p3dTuPbThXC/u2YAagVN3VLfp9HJi93hsxBChrg1Tm Aaa8Ve3T+p+W5GOSo2S47y2rJ6OgZvCpff7hb0SlyXZCO9KqQaW/EWVICymdnkAuZoGR sPrCdVFzEynH32n3DHfFpNO9A6TWOJHGIK5WSwENx4qanVIAltUSCFWLPa/rXb26CKWW tgO8Y5/vruvEr1P/QpFNlgyX8rK+C5Uipf50MiCFbp+yyKelOExUV2v+6gp9H0FAtJVB 59fg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=srSYdPpB; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id w12-20020a05640234cc00b0045cc02ce2aasi1445102edc.319.2022.10.12.12.39.48 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Oct 2022 12:39:48 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=srSYdPpB; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 426CC3860748 for <ouuuleilei@gmail.com>; Wed, 12 Oct 2022 19:39:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 426CC3860748 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1665603587; bh=TGIF4gKIVuBMTDYkFOm5NrKTsQojOXfWhnvxrjSsTug=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=srSYdPpBf2s3o/TESEfBn0v7NtqNudzweoIJDHZh5bSTv5yLPOi+mUn84L5Pu8OX5 hrCGThI7FXBhg0ivvd84jWcjz27EcTgFyLT1q6rh+vAGdLcr/PitBApf3NV37Er7La kEf/TXzz6npmVXPPlYUti0q9PMj7bOvgcr+z5Reo= 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 [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 234BB3858290 for <gcc-patches@gcc.gnu.org>; Wed, 12 Oct 2022 19:39:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 234BB3858290 Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-356-3G2B45V8Ol-gVfN3oWwfkA-1; Wed, 12 Oct 2022 15:39:03 -0400 X-MC-Unique: 3G2B45V8Ol-gVfN3oWwfkA-1 Received: by mail-qv1-f70.google.com with SMTP id y2-20020a0ce802000000b004b1ce1c4a70so10288404qvn.9 for <gcc-patches@gcc.gnu.org>; Wed, 12 Oct 2022 12:39:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=user-agent:content-disposition:mime-version:message-id:subject:cc :to:from:date:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=TGIF4gKIVuBMTDYkFOm5NrKTsQojOXfWhnvxrjSsTug=; b=O3Scs+aXfAjSwr2RgH57CBXlhsI305begGml5yxCpFSvPnTS2787SFlBzvQVgUrnnn bNh1trZS953w6CIsnOLOjKDmFk2kK6no5e3UCl6vB2fMT2kwr241HUOwo1TraYz9B/Zo qCT1N5XUU+rFGyHRPkKQmyB6qkdsFJXHHPWAn4F4AdhYfymaUoGtZyNI987GfHZ261lv BYDbw839DFerJSYLYNaBEQNLz/lu2IVTB7iZjqqJvjZ8khylE+VlSYn2mYxsmZiAFnCj 27lnmxHoLKZUJNJKRPF9+PFXkxexbmXdomaIh8psuE+gzEHxGIvzg9eNst0JAyZR9mMD OW3A== X-Gm-Message-State: ACrzQf2NUrqXjV+yopnnMjdRaiOljaMSZzUH+zk/z7VP5AZ17qa2D+64 l6h+UbB2ET5sIw+euHYjq5yYcEh/2N9y7vArDWnHRsQ2xA10PAE8F3YOMaoTuXQrXnVMioDiGbM sBloLnrWejqMGwpIuoxEh4Kp8e+ClkVZC23Wqdj1iufO8UpiH+bYcNPpHQonAf+OrLKia X-Received: by 2002:a05:620a:1923:b0:6ed:4c4d:78b5 with SMTP id bj35-20020a05620a192300b006ed4c4d78b5mr10724701qkb.97.1665603542143; Wed, 12 Oct 2022 12:39:02 -0700 (PDT) X-Received: by 2002:a05:620a:1923:b0:6ed:4c4d:78b5 with SMTP id bj35-20020a05620a192300b006ed4c4d78b5mr10724682qkb.97.1665603541854; Wed, 12 Oct 2022 12:39:01 -0700 (PDT) Received: from redhat.com (2603-7000-9500-2e39-0000-0000-0000-1db4.res6.spectrum.com. [2603:7000:9500:2e39::1db4]) by smtp.gmail.com with ESMTPSA id s20-20020a05620a29d400b006eeb3165565sm82429qkp.80.2022.10.12.12.39.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Oct 2022 12:39:01 -0700 (PDT) Date: Wed, 12 Oct 2022 15:38:59 -0400 To: GCC Patches <gcc-patches@gcc.gnu.org> Subject: [wwwdocs] porting_to: Two-stage overload resolution for implicit move removed Message-ID: <Y0cX0wQJBbmESbG1@redhat.com> MIME-Version: 1.0 User-Agent: Mutt/2.2.7 (2022-08-07) X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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 <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> From: Marek Polacek via Gcc-patches <gcc-patches@gcc.gnu.org> Reply-To: Marek Polacek <polacek@redhat.com> Cc: Jonathan Wakely <jwakely@redhat.com> Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org> X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746511948244092690?= X-GMAIL-MSGID: =?utf-8?q?1746511948244092690?= |
Series |
[wwwdocs] porting_to: Two-stage overload resolution for implicit move removed
|
|
Commit Message
Marek Polacek
Oct. 12, 2022, 7:38 p.m. UTC
As I promised in <https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603189.html>, I'd like to update our GCC 13 porting_to.html with the following note. Does this look OK to commit? Thanks,
Comments
On Wed, 12 Oct 2022 at 20:39, Marek Polacek <polacek@redhat.com> wrote: > > As I promised in > <https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603189.html>, > I'd like to update our GCC 13 porting_to.html with the following note. > > Does this look OK to commit? Thanks, > > diff --git a/htdocs/gcc-13/porting_to.html b/htdocs/gcc-13/porting_to.html > index 84a00f21..243ed29d 100644 > --- a/htdocs/gcc-13/porting_to.html > +++ b/htdocs/gcc-13/porting_to.html > @@ -42,5 +42,57 @@ be included explicitly when compiled with GCC 13: > </li> > </ul> > > +<h3 id="two-stage-or">Two-stage overload resolution for implicit move removed</h3> > +<p> > +GCC 13 removed the two-stage overload resolution when performing > +implicit move, whereby the compiler does two separate overload resolutions: > +one treating the operand as an rvalue, and then (if that resolution fails) > +another one treating the operand as an lvalue. In the standard this was > +introduced in C++11 and implemented in gcc in > +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=4ce8c5dea53d80736b9c0ba6faa7430ed65ed365"> > +r251035</a>. In > +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=1722e2013f05f1f1f99379dbaa0c0df356da731f"> > +r11-2412</a>, the fallback overload resolution was disabled in C++20 (but > +not in C++17). Then C++23 <a href="https://wg21.link/p2266">P2266</a> > +removed the fallback overload resolution, and changed the implicit move > +rules once again. > +</p> > +<p> > +The two overload resolutions approach was complicated and quirky, so users > +should transition to the newer model. This change means that code that > +previously didn't compile in C++17 will now compile, for example:</p> > + > +<pre><code> > + struct S1 { S1(S1 &&); }; > + struct S2 : S1 {}; > + > + S1 > + f (S2 s) > + { > + return s; // OK, derived-to-base, use S1::S1(S1&&) > + } > +</code></pre> > + > +<p> > +And conversely, code that used to work in C++17 may not compile anymore: > +</p> > + > +<pre><code> > + struct W { > + W(); > + }; > + > + struct F { > + F(W&); > + F(W&&) = delete; > + }; > + > + F fn () > + { > + W w; > + return w; // use w as rvalue -> use of deleted function F::F(W&&) Deleted move constructors are an abomination, and should never occur in real code. I'm not sure using one even in an example like this should be encouraged. The example added by P2266 to Annex D is more realistic (and actually broke a libstdc++ test): X& foo(X&& x) { return x; } > + } > +</code></pre> > + > </body> > </html> >
On Wed, Oct 12, 2022 at 09:50:36PM +0100, Jonathan Wakely wrote: > On Wed, 12 Oct 2022 at 20:39, Marek Polacek <polacek@redhat.com> wrote: > > > > As I promised in > > <https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603189.html>, > > I'd like to update our GCC 13 porting_to.html with the following note. > > > > Does this look OK to commit? Thanks, > > > > diff --git a/htdocs/gcc-13/porting_to.html b/htdocs/gcc-13/porting_to.html > > index 84a00f21..243ed29d 100644 > > --- a/htdocs/gcc-13/porting_to.html > > +++ b/htdocs/gcc-13/porting_to.html > > @@ -42,5 +42,57 @@ be included explicitly when compiled with GCC 13: > > </li> > > </ul> > > > > +<h3 id="two-stage-or">Two-stage overload resolution for implicit move removed</h3> > > +<p> > > +GCC 13 removed the two-stage overload resolution when performing > > +implicit move, whereby the compiler does two separate overload resolutions: > > +one treating the operand as an rvalue, and then (if that resolution fails) > > +another one treating the operand as an lvalue. In the standard this was > > +introduced in C++11 and implemented in gcc in > > +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=4ce8c5dea53d80736b9c0ba6faa7430ed65ed365"> > > +r251035</a>. In > > +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=1722e2013f05f1f1f99379dbaa0c0df356da731f"> > > +r11-2412</a>, the fallback overload resolution was disabled in C++20 (but > > +not in C++17). Then C++23 <a href="https://wg21.link/p2266">P2266</a> > > +removed the fallback overload resolution, and changed the implicit move > > +rules once again. > > +</p> > > +<p> > > +The two overload resolutions approach was complicated and quirky, so users > > +should transition to the newer model. This change means that code that > > +previously didn't compile in C++17 will now compile, for example:</p> > > + > > +<pre><code> > > + struct S1 { S1(S1 &&); }; > > + struct S2 : S1 {}; > > + > > + S1 > > + f (S2 s) > > + { > > + return s; // OK, derived-to-base, use S1::S1(S1&&) > > + } > > +</code></pre> > > + > > +<p> > > +And conversely, code that used to work in C++17 may not compile anymore: > > +</p> > > + > > +<pre><code> > > + struct W { > > + W(); > > + }; > > + > > + struct F { > > + F(W&); > > + F(W&&) = delete; > > + }; > > + > > + F fn () > > + { > > + W w; > > + return w; // use w as rvalue -> use of deleted function F::F(W&&) > > Deleted move constructors are an abomination, and should never occur > in real code. I'm not sure using one even in an example like this > should be encouraged. The example added by P2266 to Annex D is more > realistic (and actually broke a libstdc++ test): > > X& foo(X&& x) { return x; } Right, but this code still compiles in C++17, it only fails to compile in C++23. The previous example now doesn't compile even in C++17. So how about this improved patch which makes it clear that code with deleted move constructors should never occur in practice, and adds a new note, specifically about P2266 and the code you showed? Thanks for taking a look, diff --git a/htdocs/gcc-13/porting_to.html b/htdocs/gcc-13/porting_to.html index 84a00f21..a9991e8b 100644 --- a/htdocs/gcc-13/porting_to.html +++ b/htdocs/gcc-13/porting_to.html @@ -42,5 +42,71 @@ be included explicitly when compiled with GCC 13: </li> </ul> +<h3 id="P2266">Implicit move rules change</h3> +<p> +GCC 13 implements C++23 <a href="https://wg21.link/p2266">P2266</a> which +simplified the rules for implicit move. As a consequence, valid C++20 +code that relies on a returned <em>id-expression</em>'s being an lvalue +may change behavior or fail to compile in C++23. For example:</p> + +<pre><code> + decltype(auto) f(int&& x) { return (x); } // returns int&&; previously returned int& + int& g(int&& x) { return x; } // ill-formed; previously well-formed +</code></pre> + +<h3 id="two-stage-or">Two-stage overload resolution for implicit move removed</h3> +<p>GCC 13 removed the two-stage overload resolution when performing +implicit move, whereby the compiler does two separate overload resolutions: +one treating the operand as an rvalue, and then (if that resolution fails) +another one treating the operand as an lvalue. In the standard this was +introduced in C++11 and implemented in gcc in +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=4ce8c5dea53d80736b9c0ba6faa7430ed65ed365"> +r251035</a>. In +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=1722e2013f05f1f1f99379dbaa0c0df356da731f"> +r11-2412</a>, the fallback overload resolution was disabled in C++20 (but +not in C++17). Then C++23 <a href="https://wg21.link/p2266">P2266</a> +removed the fallback overload resolution, and changed the implicit move +rules once again.</p> + +<p>The two overload resolutions approach was complicated and quirky, so users +should transition to the newer model. This change means that code that +previously didn't compile in C++17 will now compile, for example:</p> + +<pre><code> + struct S1 { S1(S1 &&); }; + struct S2 : S1 {}; + + S1 + f (S2 s) + { + return s; // OK, derived-to-base, use S1::S1(S1&&) + } +</code></pre> + +<p>Conversely, code that used to work in C++17 may not compile anymore. +For example, the following example used to compile in C++11...17 because +we performed two separate overload resolutions: one treating the operand +as an rvalue, and then (if that resolution failed) another one treating +the operand as an lvalue.<br> +<strong>NB:</strong> this example is contrived because deleted move +constructors should not occur in real code.</p> + +<pre><code> + struct W { + W(); + }; + + struct F { + F(W&); + F(W&&) = delete; + }; + + F fn () + { + W w; + return w; // use w as rvalue -> use of deleted function F::F(W&&) + } +</code></pre> + </body> </html>
On Wed, 12 Oct 2022 at 23:24, Marek Polacek <polacek@redhat.com> wrote: > > On Wed, Oct 12, 2022 at 09:50:36PM +0100, Jonathan Wakely wrote: > > On Wed, 12 Oct 2022 at 20:39, Marek Polacek <polacek@redhat.com> wrote: > > > > > > As I promised in > > > <https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603189.html>, > > > I'd like to update our GCC 13 porting_to.html with the following note. > > > > > > Does this look OK to commit? Thanks, > > > > > > diff --git a/htdocs/gcc-13/porting_to.html b/htdocs/gcc-13/porting_to.html > > > index 84a00f21..243ed29d 100644 > > > --- a/htdocs/gcc-13/porting_to.html > > > +++ b/htdocs/gcc-13/porting_to.html > > > @@ -42,5 +42,57 @@ be included explicitly when compiled with GCC 13: > > > </li> > > > </ul> > > > > > > +<h3 id="two-stage-or">Two-stage overload resolution for implicit move removed</h3> > > > +<p> > > > +GCC 13 removed the two-stage overload resolution when performing > > > +implicit move, whereby the compiler does two separate overload resolutions: > > > +one treating the operand as an rvalue, and then (if that resolution fails) > > > +another one treating the operand as an lvalue. In the standard this was > > > +introduced in C++11 and implemented in gcc in > > > +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=4ce8c5dea53d80736b9c0ba6faa7430ed65ed365"> > > > +r251035</a>. In > > > +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=1722e2013f05f1f1f99379dbaa0c0df356da731f"> > > > +r11-2412</a>, the fallback overload resolution was disabled in C++20 (but > > > +not in C++17). Then C++23 <a href="https://wg21.link/p2266">P2266</a> > > > +removed the fallback overload resolution, and changed the implicit move > > > +rules once again. > > > +</p> > > > +<p> > > > +The two overload resolutions approach was complicated and quirky, so users > > > +should transition to the newer model. This change means that code that > > > +previously didn't compile in C++17 will now compile, for example:</p> > > > + > > > +<pre><code> > > > + struct S1 { S1(S1 &&); }; > > > + struct S2 : S1 {}; > > > + > > > + S1 > > > + f (S2 s) > > > + { > > > + return s; // OK, derived-to-base, use S1::S1(S1&&) > > > + } > > > +</code></pre> > > > + > > > +<p> > > > +And conversely, code that used to work in C++17 may not compile anymore: > > > +</p> > > > + > > > +<pre><code> > > > + struct W { > > > + W(); > > > + }; > > > + > > > + struct F { > > > + F(W&); > > > + F(W&&) = delete; > > > + }; > > > + > > > + F fn () > > > + { > > > + W w; > > > + return w; // use w as rvalue -> use of deleted function F::F(W&&) > > > > Deleted move constructors are an abomination, and should never occur > > in real code. I'm not sure using one even in an example like this > > should be encouraged. The example added by P2266 to Annex D is more > > realistic (and actually broke a libstdc++ test): > > > > X& foo(X&& x) { return x; } > > Right, but this code still compiles in C++17, it only fails to compile > in C++23. The previous example now doesn't compile even in C++17. So > how about this improved patch which makes it clear that code with > deleted move constructors should never occur in practice, and adds a new > note, specifically about P2266 and the code you showed? Doh, I've just realised that F(W&&) isn't a move ctor at all. For some reason I read the example as F(F&&). I think your original example is fine, and the note would just be confusing (because it's not a deleted move ctor!) > > Thanks for taking a look, > > diff --git a/htdocs/gcc-13/porting_to.html b/htdocs/gcc-13/porting_to.html > index 84a00f21..a9991e8b 100644 > --- a/htdocs/gcc-13/porting_to.html > +++ b/htdocs/gcc-13/porting_to.html > @@ -42,5 +42,71 @@ be included explicitly when compiled with GCC 13: > </li> > </ul> > > +<h3 id="P2266">Implicit move rules change</h3> > +<p> > +GCC 13 implements C++23 <a href="https://wg21.link/p2266">P2266</a> which > +simplified the rules for implicit move. As a consequence, valid C++20 > +code that relies on a returned <em>id-expression</em>'s being an lvalue > +may change behavior or fail to compile in C++23. For example:</p> > + > +<pre><code> > + decltype(auto) f(int&& x) { return (x); } // returns int&&; previously returned int& > + int& g(int&& x) { return x; } // ill-formed; previously well-formed > +</code></pre> > + > +<h3 id="two-stage-or">Two-stage overload resolution for implicit move removed</h3> > +<p>GCC 13 removed the two-stage overload resolution when performing > +implicit move, whereby the compiler does two separate overload resolutions: > +one treating the operand as an rvalue, and then (if that resolution fails) > +another one treating the operand as an lvalue. In the standard this was > +introduced in C++11 and implemented in gcc in > +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=4ce8c5dea53d80736b9c0ba6faa7430ed65ed365"> > +r251035</a>. In > +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=1722e2013f05f1f1f99379dbaa0c0df356da731f"> > +r11-2412</a>, the fallback overload resolution was disabled in C++20 (but > +not in C++17). Then C++23 <a href="https://wg21.link/p2266">P2266</a> > +removed the fallback overload resolution, and changed the implicit move > +rules once again.</p> > + > +<p>The two overload resolutions approach was complicated and quirky, so users > +should transition to the newer model. This change means that code that > +previously didn't compile in C++17 will now compile, for example:</p> > + > +<pre><code> > + struct S1 { S1(S1 &&); }; > + struct S2 : S1 {}; > + > + S1 > + f (S2 s) > + { > + return s; // OK, derived-to-base, use S1::S1(S1&&) > + } > +</code></pre> > + > +<p>Conversely, code that used to work in C++17 may not compile anymore. > +For example, the following example used to compile in C++11...17 because > +we performed two separate overload resolutions: one treating the operand > +as an rvalue, and then (if that resolution failed) another one treating > +the operand as an lvalue.<br> > +<strong>NB:</strong> this example is contrived because deleted move > +constructors should not occur in real code.</p> > + > +<pre><code> > + struct W { > + W(); > + }; > + > + struct F { > + F(W&); > + F(W&&) = delete; > + }; > + > + F fn () > + { > + W w; > + return w; // use w as rvalue -> use of deleted function F::F(W&&) > + } > +</code></pre> > + > </body> > </html> >
On Wed, Oct 12, 2022 at 11:38:01PM +0100, Jonathan Wakely wrote: > On Wed, 12 Oct 2022 at 23:24, Marek Polacek <polacek@redhat.com> wrote: > > > > On Wed, Oct 12, 2022 at 09:50:36PM +0100, Jonathan Wakely wrote: > > > On Wed, 12 Oct 2022 at 20:39, Marek Polacek <polacek@redhat.com> wrote: > > > > > > > > As I promised in > > > > <https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603189.html>, > > > > I'd like to update our GCC 13 porting_to.html with the following note. > > > > > > > > Does this look OK to commit? Thanks, > > > > > > > > diff --git a/htdocs/gcc-13/porting_to.html b/htdocs/gcc-13/porting_to.html > > > > index 84a00f21..243ed29d 100644 > > > > --- a/htdocs/gcc-13/porting_to.html > > > > +++ b/htdocs/gcc-13/porting_to.html > > > > @@ -42,5 +42,57 @@ be included explicitly when compiled with GCC 13: > > > > </li> > > > > </ul> > > > > > > > > +<h3 id="two-stage-or">Two-stage overload resolution for implicit move removed</h3> > > > > +<p> > > > > +GCC 13 removed the two-stage overload resolution when performing > > > > +implicit move, whereby the compiler does two separate overload resolutions: > > > > +one treating the operand as an rvalue, and then (if that resolution fails) > > > > +another one treating the operand as an lvalue. In the standard this was > > > > +introduced in C++11 and implemented in gcc in > > > > +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=4ce8c5dea53d80736b9c0ba6faa7430ed65ed365"> > > > > +r251035</a>. In > > > > +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=1722e2013f05f1f1f99379dbaa0c0df356da731f"> > > > > +r11-2412</a>, the fallback overload resolution was disabled in C++20 (but > > > > +not in C++17). Then C++23 <a href="https://wg21.link/p2266">P2266</a> > > > > +removed the fallback overload resolution, and changed the implicit move > > > > +rules once again. > > > > +</p> > > > > +<p> > > > > +The two overload resolutions approach was complicated and quirky, so users > > > > +should transition to the newer model. This change means that code that > > > > +previously didn't compile in C++17 will now compile, for example:</p> > > > > + > > > > +<pre><code> > > > > + struct S1 { S1(S1 &&); }; > > > > + struct S2 : S1 {}; > > > > + > > > > + S1 > > > > + f (S2 s) > > > > + { > > > > + return s; // OK, derived-to-base, use S1::S1(S1&&) > > > > + } > > > > +</code></pre> > > > > + > > > > +<p> > > > > +And conversely, code that used to work in C++17 may not compile anymore: > > > > +</p> > > > > + > > > > +<pre><code> > > > > + struct W { > > > > + W(); > > > > + }; > > > > + > > > > + struct F { > > > > + F(W&); > > > > + F(W&&) = delete; > > > > + }; > > > > + > > > > + F fn () > > > > + { > > > > + W w; > > > > + return w; // use w as rvalue -> use of deleted function F::F(W&&) > > > > > > Deleted move constructors are an abomination, and should never occur > > > in real code. I'm not sure using one even in an example like this > > > should be encouraged. The example added by P2266 to Annex D is more > > > realistic (and actually broke a libstdc++ test): > > > > > > X& foo(X&& x) { return x; } > > > > Right, but this code still compiles in C++17, it only fails to compile > > in C++23. The previous example now doesn't compile even in C++17. So > > how about this improved patch which makes it clear that code with > > deleted move constructors should never occur in practice, and adds a new > > note, specifically about P2266 and the code you showed? > > Doh, I've just realised that F(W&&) isn't a move ctor at all. For some > reason I read the example as F(F&&). And so did I while adding the note :[. > I think your original example is fine, and the note would just be > confusing (because it's not a deleted move ctor!) I think I'll go ahead with this, then (I've removed the NB). Thanks! diff --git a/htdocs/gcc-13/porting_to.html b/htdocs/gcc-13/porting_to.html index 84a00f21..ccd3f08f 100644 --- a/htdocs/gcc-13/porting_to.html +++ b/htdocs/gcc-13/porting_to.html @@ -42,5 +42,69 @@ be included explicitly when compiled with GCC 13: </li> </ul> +<h3 id="P2266">Implicit move rules change</h3> +<p> +GCC 13 implements C++23 <a href="https://wg21.link/p2266">P2266</a> which +simplified the rules for implicit move. As a consequence, valid C++20 +code that relies on a returned <em>id-expression</em>'s being an lvalue +may change behavior or fail to compile in C++23. For example:</p> + +<pre><code> + decltype(auto) f(int&& x) { return (x); } // returns int&&; previously returned int& + int& g(int&& x) { return x; } // ill-formed; previously well-formed +</code></pre> + +<h3 id="two-stage-or">Two-stage overload resolution for implicit move removed</h3> +<p>GCC 13 removed the two-stage overload resolution when performing +implicit move, whereby the compiler does two separate overload resolutions: +one treating the operand as an rvalue, and then (if that resolution fails) +another one treating the operand as an lvalue. In the standard this was +introduced in C++11 and implemented in gcc in +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=4ce8c5dea53d80736b9c0ba6faa7430ed65ed365"> +r251035</a>. In +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=1722e2013f05f1f1f99379dbaa0c0df356da731f"> +r11-2412</a>, the fallback overload resolution was disabled in C++20 (but +not in C++17). Then C++23 <a href="https://wg21.link/p2266">P2266</a> +removed the fallback overload resolution, and changed the implicit move +rules once again.</p> + +<p>The two overload resolutions approach was complicated and quirky, so users +should transition to the newer model. This change means that code that +previously didn't compile in C++17 will now compile, for example:</p> + +<pre><code> + struct S1 { S1(S1 &&); }; + struct S2 : S1 {}; + + S1 + f (S2 s) + { + return s; // OK, derived-to-base, use S1::S1(S1&&) + } +</code></pre> + +<p>Conversely, code that used to work in C++17 may not compile anymore. +For example, the following example used to compile in C++11...17 because +we performed two separate overload resolutions: one treating the operand +as an rvalue, and then (if that resolution failed) another one treating +the operand as an lvalue.<br> + +<pre><code> + struct W { + W(); + }; + + struct F { + F(W&); + F(W&&) = delete; + }; + + F fn () + { + W w; + return w; // use w as rvalue -> use of deleted function F::F(W&&) + } +</code></pre> + </body> </html>
diff --git a/htdocs/gcc-13/porting_to.html b/htdocs/gcc-13/porting_to.html index 84a00f21..243ed29d 100644 --- a/htdocs/gcc-13/porting_to.html +++ b/htdocs/gcc-13/porting_to.html @@ -42,5 +42,57 @@ be included explicitly when compiled with GCC 13: </li> </ul> +<h3 id="two-stage-or">Two-stage overload resolution for implicit move removed</h3> +<p> +GCC 13 removed the two-stage overload resolution when performing +implicit move, whereby the compiler does two separate overload resolutions: +one treating the operand as an rvalue, and then (if that resolution fails) +another one treating the operand as an lvalue. In the standard this was +introduced in C++11 and implemented in gcc in +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=4ce8c5dea53d80736b9c0ba6faa7430ed65ed365"> +r251035</a>. In +<a href="https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=1722e2013f05f1f1f99379dbaa0c0df356da731f"> +r11-2412</a>, the fallback overload resolution was disabled in C++20 (but +not in C++17). Then C++23 <a href="https://wg21.link/p2266">P2266</a> +removed the fallback overload resolution, and changed the implicit move +rules once again. +</p> +<p> +The two overload resolutions approach was complicated and quirky, so users +should transition to the newer model. This change means that code that +previously didn't compile in C++17 will now compile, for example:</p> + +<pre><code> + struct S1 { S1(S1 &&); }; + struct S2 : S1 {}; + + S1 + f (S2 s) + { + return s; // OK, derived-to-base, use S1::S1(S1&&) + } +</code></pre> + +<p> +And conversely, code that used to work in C++17 may not compile anymore: +</p> + +<pre><code> + struct W { + W(); + }; + + struct F { + F(W&); + F(W&&) = delete; + }; + + F fn () + { + W w; + return w; // use w as rvalue -> use of deleted function F::F(W&&) + } +</code></pre> + </body> </html>