On 6/25/24 11:03, Patrick Palka wrote:
On Mon, 24 Jun 2024, Jason Merrill wrote:

On 6/24/24 21:00, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK
for trunk/14?

-- >8 --

The capture proxy handling in finish_decltype_type added in r14-5330
was stripping the reference type of a capture proxy's captured variable,
which is desirable for a by-value capture, but not for a by-ref capture
(of a reference).

I'm not sure why we would want it for by-value, either; regardless of the
capture kind, decltype(x) is int&.

Ah, makes sense.  But I guess that means

   void f(int& x) {
     [x]() {
       decltype(auto) a = x;
     }
   }

is ill-formed since decltype(x) is int& but the corresponding closure
member is const?  It works if we make the lambda mutable.

Yes, and clang agrees.  Let's also test that case.

Like so?  Bootstrapped and regtested on x86_64-pc-linux-gnu.


-- >8 --

Subject: [PATCH] c++: decltype of capture proxy of ref [PR115504]

The capture proxy handling in finish_decltype_type added in r14-5330
was stripping the reference type of a capture proxy's captured variable.

        PR c++/115504

gcc/cp/ChangeLog:

        * semantics.cc (finish_decltype_type): Don't strip the reference
        type (if any) of a capture proxy's captured variable.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp1y/decltype-auto8.C: New test.
---
  gcc/cp/semantics.cc                         |  1 -
  gcc/testsuite/g++.dg/cpp1y/decltype-auto8.C | 18 ++++++++++++++++++
  2 files changed, 18 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp1y/decltype-auto8.C

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 6c1813d37c6..6a383c0f7f9 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12071,7 +12071,6 @@ finish_decltype_type (tree expr, bool 
id_expression_or_member_access_p,
                {
                  expr = DECL_CAPTURED_VARIABLE (expr);
                  type = TREE_TYPE (expr);
-                 type = non_reference (type);
                }
              else
                {
diff --git a/gcc/testsuite/g++.dg/cpp1y/decltype-auto8.C 
b/gcc/testsuite/g++.dg/cpp1y/decltype-auto8.C
new file mode 100644
index 00000000000..1100b94a5b7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/decltype-auto8.C
@@ -0,0 +1,18 @@
+// PR c++/115504
+// { dg-do compile { target c++14 } }
+
+void f(int& x) {
+  [&x]() {
+    decltype(auto) a = x;
+    using type = decltype(x);
+    using type = decltype(a);
+    using type = int&; // not 'int'
+  };
+
+  [x]() mutable {
+    decltype(auto) a = x;
+    using type = decltype(x);
+    using type = decltype(a);
+    using type = int&;
+  };
+}

Reply via email to