]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: alias CTAD and copy deduction guide [PR115198]
authorPatrick Palka <ppalka@redhat.com>
Tue, 25 Jun 2024 16:59:24 +0000 (12:59 -0400)
committerPatrick Palka <ppalka@redhat.com>
Tue, 25 Jun 2024 16:59:24 +0000 (12:59 -0400)
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>
(i.e. 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 the transformed
guides.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/class-deduction-alias22.C: New test.

Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/pt.cc
gcc/testsuite/g++.dg/cpp2a/class-deduction-alias22.C [new file with mode: 0644]

index 607753ae6b7f43e26649aa9093fda20580a2424a..daa8ac386dc9512a6e1fe7209236201f97f4c2e3 100644 (file)
@@ -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 (file)
index 0000000..9c6c841
--- /dev/null
@@ -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" }