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. 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&; + }; +} -- 2.45.2.648.g1e1586e4ed > > > PR c++/115504 > > > > gcc/cp/ChangeLog: > > > > * semantics.cc (finish_decltype_type): For a by-reference > > capture proxy, don't strip the reference type (if any) of > > the captured variable. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp1y/decltype-auto8.C: New test. > > --- > > gcc/cp/semantics.cc | 4 +++- > > gcc/testsuite/g++.dg/cpp1y/decltype-auto8.C | 11 +++++++++++ > > 2 files changed, 14 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 08f5f245e7d..b4f626924af 100644 > > --- a/gcc/cp/semantics.cc > > +++ b/gcc/cp/semantics.cc > > @@ -12076,9 +12076,11 @@ finish_decltype_type (tree expr, bool > > id_expression_or_member_access_p, > > { > > if (is_normal_capture_proxy (expr)) > > { > > + bool by_ref = TYPE_REF_P (TREE_TYPE (expr)); > > expr = DECL_CAPTURED_VARIABLE (expr); > > type = TREE_TYPE (expr); > > - type = non_reference (type); > > + if (!by_ref) > > + 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..9a5e435f14f > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/cpp1y/decltype-auto8.C > > @@ -0,0 +1,11 @@ > > +// 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' > > + }; > > +} > >