On Thu, 13 Jun 2024, Patrick Palka wrote: > On Thu, 13 Jun 2024, Jason Merrill wrote: > > > On 6/13/24 11:05, Patrick Palka wrote: > > > On Thu, 23 May 2024, Jason Merrill wrote: > > > > > > > On 5/23/24 17:42, Patrick Palka wrote: > > > > > On Thu, 23 May 2024, Jason Merrill wrote: > > > > > > > > > > > On 5/23/24 14:06, Patrick Palka wrote: > > > > > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look > > > > > > > OK for trunk/14? > > > > > > > > > > > > > > -- >8 -- > > > > > > > > > > > > > > Here we're neglecting to update DECL_NAME during the alias CTAD > > > > > > > guide > > > > > > > transformation, which causes copy_guide_p to return false for the > > > > > > > transformed copy deduction guide since DECL_NAME is still > > > > > > > __dguide_C > > > > > > > with TREE_TYPE C<B, T> but it should be __dguide_A with TREE_TYPE > > > > > > > A<T> > > > > > > > (equivalently C<false, T>). This ultimately results in ambiguity > > > > > > > during > > > > > > > overload resolution between the copy deduction guide vs copy ctor > > > > > > > guide. > > > > > > > > > > > > > > This patch makes us update DECL_NAME of a transformed guide > > > > > > > accordingly > > > > > > > during alias CTAD. This eventually needs to be done for inherited > > > > > > > CTAD > > > > > > > too, but it's not clear what identifier to use there since it has > > > > > > > to > > > > > > > be > > > > > > > unique for each derived/base pair. For > > > > > > > > > > > > > > template<bool B, class T> struct A { ... }; > > > > > > > template<class T> struct B : A<false, T> { using A<false, > > > > > > > T>::A; } > > > > > > > > > > > > > > at first glance it'd be reasonable to give inherited guides a name > > > > > > > of > > > > > > > __dguide_B with TREE_TYPE A<false, T>, but since that name is > > > > > > > already > > > > > > > used B's own guides its TREE_TYPE is already B<T>. > > > > > > > > > > > > Why can't it be the same __dguide_B with TREE_TYPE B<T>? > > > > > > > > > > Ah because copy_guide_p relies on TREE_TYPE in order to recognize a > > > > > copy > > > > > deduction guide, and with that TREE_TYPE it would still incorrectly > > > > > return false for an inherited copy deduction guide, e.g. > > > > > > > > > > A(A<B, T>) -> A<B, T> > > > > > > > > > > gets transformed into > > > > > > > > > > B(A<false, T>) -> B<T> > > > > > > > > > > and A<false, T> != B<T> so copy_guide_p returns false. > > > > > > > > Hmm, that seems correct; the transformed candidate is not the copy > > > > deduction > > > > guide for B. > > > > > > By https://eel.is/c++draft/over.match.class.deduct#3.4 it seems that a > > > class template can now have multiple copy deduction guides with inherited > > > CTAD: the derived class's own copy guide, along with the transformed copy > > > guides of its eligible base classes. Do we want to follow the standard > > > precisely here, or should we maybe restrict the copy-guideness propagation > > > to alias CTAD only? > > > > The latter, I think; it seems nonsensical to have multiple copy guides. > > Sounds good, so for inherited CTAD it should suffice to use __dguide_B > as the name (where B is the derived class), like so?
Ping. > > -- >8 -- > > Subject: [PATCH] c++: alias CTAD and copy deduction guide [PR115198] > > Here we're neglecting to update DECL_NAME during the alias CTAD guide > transformation, which causes copy_guide_p to return false for the > transformed copy deduction guide since DECL_NAME is still __dguide_C > with TREE_TYPE C<B, T> but it should be __dguide_A with TREE_TYPE A<T> > (equivalently C<false, T>). This ultimately results in ambiguity during > overload resolution between the copy deduction guide vs copy ctor guide. > > This patch makes us update DECL_NAME of a transformed guide accordingly > during alias/inherited CTAD. > > PR c++/115198 > > gcc/cp/ChangeLog: > > * pt.cc (alias_ctad_tweaks): Update DECL_NAME of a transformed > guide. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/class-deduction-alias22.C: New test. > --- > gcc/cp/pt.cc | 6 +++++- > .../g++.dg/cpp2a/class-deduction-alias22.C | 14 ++++++++++++++ > 2 files changed, 19 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-alias22.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 607753ae6b7..daa8ac386dc 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -30342,13 +30342,14 @@ alias_ctad_tweaks (tree tmpl, tree uguides) > any). */ > > enum { alias, inherited } ctad_kind; > - tree atype, fullatparms, utype; > + tree atype, fullatparms, utype, name; > if (TREE_CODE (tmpl) == TEMPLATE_DECL) > { > ctad_kind = alias; > atype = TREE_TYPE (tmpl); > fullatparms = DECL_TEMPLATE_PARMS (tmpl); > utype = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl)); > + name = dguide_name (tmpl); > } > else > { > @@ -30356,6 +30357,8 @@ alias_ctad_tweaks (tree tmpl, tree uguides) > atype = NULL_TREE; > fullatparms = TREE_PURPOSE (tmpl); > utype = TREE_VALUE (tmpl); > + name = dguide_name (TPARMS_PRIMARY_TEMPLATE > + (INNERMOST_TEMPLATE_PARMS (fullatparms))); > } > > tsubst_flags_t complain = tf_warning_or_error; > @@ -30451,6 +30454,7 @@ alias_ctad_tweaks (tree tmpl, tree uguides) > } > if (g == error_mark_node) > continue; > + DECL_NAME (g) = name; > if (nfparms == 0) > { > /* The targs are all non-dependent, so g isn't a template. */ > diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias22.C > b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias22.C > new file mode 100644 > index 00000000000..9c6c841166a > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias22.C > @@ -0,0 +1,14 @@ > +// PR c++/115198 > +// { dg-do compile { target c++20 } } > + > +template<bool B, class T> > +struct C { > + C() = default; > + C(const C&) = default; > +}; > + > +template<class T> > +using A = C<false, T>; > + > +C<false, int> c; > +A a = c; // { dg-bogus "ambiguous" } > -- > 2.45.2.492.gd63586cb31 > > > > > > Jason > > > > > > > But it just occurred to me that this TREE_TYPE clobbering of the > > > > > __dguide_foo identifier already happens if we have two class templates > > > > > with the same name in different namespaces, since the identifier > > > > > contains only the terminal name. Maybe this suggests that we should > > > > > use a tree flag to track whether a guide is the copy deduction guide > > > > > instead of setting TREE_TYPE of DECL_NAME? > > > > > > > > Good point. > > > > > > > > Jason > > > > > > > > > > > > > > > >