public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Marek Polacek <polacek@redhat.com>
To: Jason Merrill <jason@redhat.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] c++: Implement C++23 P2266R1, Simpler implicit move [PR101165]
Date: Tue, 20 Sep 2022 14:21:18 -0400	[thread overview]
Message-ID: <YyoEnvGzeTMrlRJG@redhat.com> (raw)
In-Reply-To: <3cfe2791-914e-1b7c-b874-2fcc34f2c240@redhat.com>

On Mon, Sep 12, 2022 at 04:27:27PM -0400, Jason Merrill wrote:
> On 9/8/22 18:54, Marek Polacek wrote:
> > On Tue, Sep 06, 2022 at 10:38:12PM -0400, Jason Merrill wrote:
> > > On 9/3/22 12:42, Marek Polacek wrote:
> > > > This patch implements https://wg21.link/p2266, which, once again,
> > > > changes the implicit move rules.  Here's a brief summary of various
> > > > changes in this area:
> > > > 
> > > > r125211: Introduced moving from certain lvalues when returning them
> > > > r171071: CWG 1148, enable move from value parameter on return
> > > > r212099: CWG 1579, it's OK to call a converting ctor taking an rvalue
> > > > r251035: CWG 1579, do maybe-rvalue overload resolution twice
> > > > r11-2411: Avoid calling const copy ctor on implicit move
> > > > r11-2412: C++20 implicit move changes, remove the fallback overload
> > > >             resolution, allow move on throw of parameters and implicit
> > > > 	  move of rvalue references
> > > > 
> > > > P2266 enables the implicit move for functions that return references.  This
> > > > was a one-line change: check TYPE_REF_P.  That is, we will now perform
> > > > a move in
> > > > 
> > > >     X&& foo (X&& x) {
> > > >       return x;
> > > >     }
> > > > 
> > > > P2266 also removes the fallback overload resolution, but this was
> > > > resolved by r11-2412: we only do convert_for_initialization with
> > > > LOOKUP_PREFER_RVALUE in C++17 and older.
> > > 
> > > I wonder if we want to extend the current C++20 handling to the older modes
> > > for GCC 13?  Not in this patch, but as a followup.
> > > 
> > > > P2266 also says that a returned move-eligible id-expression is always an
> > > > xvalue.  This required some further short, but nontrivial changes,
> > > > especially when it comes to deduction, because we have to pay attention
> > > > to whether we have auto, auto&& (which is like T&&), or decltype(auto)
> > > > with (un)parenthesized argument.  In C++23,
> > > > 
> > > >     decltype(auto) f(int&& x) { return (x); }
> > > >     auto&& f(int x) { return x; }
> > > > 
> > > > both should deduce to 'int&&' but
> > > > 
> > > >     decltype(auto) f(int x) { return x; }
> > > > 
> > > > should deduce to 'int'.  A cornucopia of tests attached.  I've also
> > > > verified that we behave like clang++.
> > > > 
> > > > xvalue_p seemed to be broken: since the introduction of clk_implicit_rval,
> > > > it cannot use '==' when checking for clk_rvalueref.
> > > > 
> > > > Since this change breaks code, it's only enabled in C++23.  In
> > > > particular, this code will not compile in C++23:
> > > > 
> > > >     int& g(int&& x) { return x; }
> > > 
> > > Nice that the C++20 compatibility is so simple!
> > > 
> > > > because x is now treated as an rvalue, and you can't bind a non-const lvalue
> > > > reference to an rvalue.
> > > > 
> > > > There's one FIXME in elision1.C:five, which we should compile but reject
> > > > with "passing 'Mutt' as 'this' argument discards qualifiers".  That
> > > > looks bogus to me, I think I'll open a PR for it.
> > > 
> > > Let's fix that now, I think.
> > 
> > Can of worms.   The test is
> > 
> >    struct Mutt {
> >        operator int*() &&;
> >    };
> > 
> >    int* five(Mutt x) {
> >        return x;  // OK since C++20 because P1155
> >    }
> > 
> > 'x' should be treated as an rvalue, therefore the operator fn taking
> > an rvalue ref to Mutt should be used to convert 'x' to int*.  We fail
> > because we don't treat 'x' as an rvalue because the function doesn't
> > return a class.  So the patch should be just
> > 
> > --- a/gcc/cp/typeck.cc
> > +++ b/gcc/cp/typeck.cc
> > @@ -10875,10 +10875,7 @@ check_return_expr (tree retval, bool *no_warning)
> >            Note that these conditions are similar to, but not as strict as,
> >       the conditions for the named return value optimization.  */
> >         bool converted = false;
> > -      tree moved;
> > -      /* This is only interesting for class type.  */
> > -      if (CLASS_TYPE_P (functype)
> > -     && (moved = treat_lvalue_as_rvalue_p (retval, /*return*/true)))
> > +      if (tree moved = treat_lvalue_as_rvalue_p (retval, /*return*/true))
> >      {
> >        if (cxx_dialect < cxx20)
> >          {
> > 
> > which fixes the test, but breaks a lot of middle-end warnings.  For instance
> > g++.dg/warn/nonnull3.C, where the patch above changes .gimple:
> > 
> >   bool A::foo<B> (struct A * const this, <<< Unknown tree: offset_type >>> p)
> >   {
> > -  bool D.2146;
> > +  bool D.2150;
> > -  D.2146 = p != -1;
> > -  return D.2146;
> > +  p.0_1 = p;
> > +  D.2150 = p.0_1 != -1;
> > +  return D.2150;
> >   }
> > 
> > and we no longer get the warning.  I thought maybe I could undo the implicit
> > rvalue conversion in cp_fold, when it sees implicit_rvalue_p, but that didn't
> > work.  So currently I'm stuck.  Should we try to figure this out or push aside?
> 
> Can you undo the implicit rvalue conversion within check_return_expr, where
> we can still refer back to the original expression?
> 
> Or avoid the rvalue conversion if the return type is scalar?
> 
> Did you see my comments in the body of the patch?

I responded in the email I just sent so that we can have a single thread.

Marek


  reply	other threads:[~2022-09-20 18:21 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-03 16:42 Marek Polacek
2022-09-07  2:38 ` Jason Merrill
2022-09-08 22:54   ` Marek Polacek
2022-09-12 20:27     ` Jason Merrill
2022-09-20 18:21       ` Marek Polacek [this message]
2022-09-20 18:19   ` [PATCH v2] " Marek Polacek
2022-09-26 17:29     ` Jason Merrill
2022-09-27 20:26       ` [PATCH v3] " Marek Polacek
2022-09-27 21:44         ` Jason Merrill
2022-09-27 23:39           ` Marek Polacek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YyoEnvGzeTMrlRJG@redhat.com \
    --to=polacek@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).