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: Thu, 8 Sep 2022 18:54:06 -0400	[thread overview]
Message-ID: <YxpyjkXvRFoKKoL8@redhat.com> (raw)
In-Reply-To: <9f9f6d62-c3c8-083e-d30d-808076c01eca@redhat.com>

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?

Marek


  reply	other threads:[~2022-09-08 22:54 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 [this message]
2022-09-12 20:27     ` Jason Merrill
2022-09-20 18:21       ` Marek Polacek
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=YxpyjkXvRFoKKoL8@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).