On Mon, 16 Sep 2024, Patrick Palka wrote: > On Mon, 16 Sep 2024, Andrew Pinski wrote: > > > On Mon, Sep 16, 2024 at 8:12 AM Patrick Palka <ppa...@redhat.com> wrote: > > > > > > Bootstrapped and regtested on x86_64-pc-linuxgnu, does this look > > > OK for trunk? Sadly the prerequisity patch r15-2331-g523836716137d0 > > > probably isn't suitable for backporting, so I reckon this should be > > > trunk-only. > > > > > > -- >8 -- > > > > > > Here we're prematurely stripping the decltype(lambda) alias used inside > > > the template-id during ahead of time template argument coercion, which > > > means we treat it as if it were > > > > > > is_same_v<decltype([]{}), decltype([]{})> > > > > > > which instead yields false since now we're substituting into the lambda > > > twice, and every such substitution yields a unique lambda. This > > > demonstrates that such aliases should be considered opaque, a notion which > > > coincidentally we recently introduced in r15-2331-g523836716137d0. > > > > I wonder if this fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106221 > > too. > > While https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107390 looks it > > would be fixed here too. > > Ah thanks, seems 107390 gets fixed but not 106221..
Here's v2 which extends the testcase slightly to also subsume the PR107390 testcase. It also slightly refines the predicate to treat ty2 in using ty1 = decltype([]{}); using ty2 = ty1; as _not_ opaque (unlike ty1), since we should be able to strip it to ty1. I don't know if this makes a difference but it seems the conceptually right thing to do. -- >8 -- Subject: [PATCH] c++: alias of decltype(lambda) is opaque [PR116714, PR107390] PR c++/116714 PR c++/107390 gcc/cp/ChangeLog: * pt.cc (dependent_opaque_alias_p): Also return true for a decltype(lambda) alias. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-uneval18.C: New test. --- gcc/cp/pt.cc | 7 +++- gcc/testsuite/g++.dg/cpp2a/lambda-uneval18.C | 39 ++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-uneval18.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 04987f66746..b29ea164a91 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -6764,8 +6764,11 @@ dependent_opaque_alias_p (const_tree t) { return (TYPE_P (t) && typedef_variant_p (t) - && any_dependent_type_attributes_p (DECL_ATTRIBUTES - (TYPE_NAME (t)))); + && (any_dependent_type_attributes_p (DECL_ATTRIBUTES + (TYPE_NAME (t))) + || (TREE_CODE (t) == DECLTYPE_TYPE + && TREE_CODE (DECLTYPE_TYPE_EXPR (t)) == LAMBDA_EXPR + && !typedef_variant_p (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))))); } /* Return the number of innermost template parameters in TMPL. */ diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval18.C b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval18.C new file mode 100644 index 00000000000..b7d864c6245 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval18.C @@ -0,0 +1,39 @@ +// PR c++/116714 +// PR c++/107390 +// { dg-do compile { target c++20 } } + +template<class T, class U> +inline constexpr bool is_same_v = __is_same(T, U); + +template<class T, class U> +struct is_same { static constexpr bool value = false; }; + +template<class T> +struct is_same<T, T> { static constexpr bool value = true; }; + +template<class> +void f() { + using type = decltype([]{}); + static_assert(is_same_v<type, type>); + static_assert(is_same<type, type>::value); +}; + +template<class> +void g() { + using ty1 = decltype([]{}); + using ty2 = ty1; + static_assert(is_same_v<ty1, ty2>); + static_assert(is_same<ty1, ty2>::value); +}; + +template<class> +void h() { + using ty1 = decltype([]{}); + using ty2 = decltype([]{}); + static_assert(!is_same_v<ty1, ty2>); + static_assert(!is_same<ty1, ty2>::value); +}; + +template void f<int>(); +template void g<int>(); +template void h<int>(); -- 2.46.1.544.g3fb745257b > > > > > Thanks, > > Andrew > > > > > > > > PR c++/116714 > > > > > > gcc/cp/ChangeLog: > > > > > > * pt.cc (dependent_opaque_alias_p): Also return true for a > > > decltype(lambda) alias. > > > > > > gcc/testsuite/ChangeLog: > > > > > > * g++.dg/cpp2a/lambda-uneval18.C: New test. > > > --- > > > gcc/cp/pt.cc | 6 ++++-- > > > gcc/testsuite/g++.dg/cpp2a/lambda-uneval18.C | 20 ++++++++++++++++++++ > > > 2 files changed, 24 insertions(+), 2 deletions(-) > > > create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-uneval18.C > > > > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > > > index 04987f66746..a72a1eadbc7 100644 > > > --- a/gcc/cp/pt.cc > > > +++ b/gcc/cp/pt.cc > > > @@ -6764,8 +6764,10 @@ dependent_opaque_alias_p (const_tree t) > > > { > > > return (TYPE_P (t) > > > && typedef_variant_p (t) > > > - && any_dependent_type_attributes_p (DECL_ATTRIBUTES > > > - (TYPE_NAME (t)))); > > > + && (any_dependent_type_attributes_p (DECL_ATTRIBUTES > > > + (TYPE_NAME (t))) > > > + || (TREE_CODE (t) == DECLTYPE_TYPE > > > + && TREE_CODE (DECLTYPE_TYPE_EXPR (t)) == LAMBDA_EXPR))); > > > } > > > > > > /* Return the number of innermost template parameters in TMPL. */ > > > diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval18.C > > > b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval18.C > > > new file mode 100644 > > > index 00000000000..2942f8305c7 > > > --- /dev/null > > > +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval18.C > > > @@ -0,0 +1,20 @@ > > > +// PR c++/116714 > > > +// { dg-do compile { target c++20 } } > > > + > > > +template<class T, class U> > > > +inline constexpr bool is_same_v = __is_same(T, U); > > > + > > > +template<class T, class U> > > > +struct is_same { static constexpr bool value = false; }; > > > + > > > +template<class T> > > > +struct is_same<T, T> { static constexpr bool value = true; }; > > > + > > > +template<class> > > > +void f() { > > > + using type = decltype([]{}); > > > + static_assert(is_same_v<type, type>); > > > + static_assert(is_same<type, type>::value); > > > +}; > > > + > > > +template void f<int>(); > > > -- > > > 2.46.1.506.ged155187b4 > > > > > > >