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>?

        PR c++/115198

gcc/cp/ChangeLog:

        * pt.cc (alias_ctad_tweaks): Update DECL_NAME of a transformed
        guide during alias CTAD.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp2a/class-deduction-alias22.C: New test.
---
  gcc/cp/pt.cc                                       |  9 ++++++++-
  .../g++.dg/cpp2a/class-deduction-alias22.C         | 14 ++++++++++++++
  2 files changed, 22 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 0c4d96cf768..58873057abc 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -30304,13 +30304,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
      {
@@ -30318,6 +30319,10 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
        atype = NULL_TREE;
        fullatparms = TREE_PURPOSE (tmpl);
        utype = TREE_VALUE (tmpl);
+      /* FIXME: What name should we give inherited guides?  It needs to be
+        unique to the derived/base pair so that we don't clobber an earlier
+        setting of TREE_TYPE.  */
+      name = NULL_TREE;
      }
tsubst_flags_t complain = tf_warning_or_error;
@@ -30413,6 +30418,8 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
            }
          if (g == error_mark_node)
            continue;
+         if (name)
+           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" }

Reply via email to