diff options
author | Patrick Palka <ppalka@redhat.com> | 2024-06-25 12:59:24 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2024-06-28 15:43:52 -0400 |
commit | a00a8d46ea6ff7130e2493e7bd9824e28e2509b7 (patch) | |
tree | 40624cb613ea9e8ae18f2980fcd235ff767e188c | |
parent | 33a9c4dd5fcac7e3f5d835b35fe787126339dd2b (diff) | |
download | gcc-a00a8d46ea6ff7130e2493e7bd9824e28e2509b7.zip gcc-a00a8d46ea6ff7130e2493e7bd9824e28e2509b7.tar.gz gcc-a00a8d46ea6ff7130e2493e7bd9824e28e2509b7.tar.bz2 |
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>
(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>
(cherry picked from commit 06ebb7c6f31fe42ffdea6f51ac1ba1f6b058c090)
-rw-r--r-- | gcc/cp/pt.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/class-deduction-alias22.C | 14 |
2 files changed, 19 insertions, 1 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c7aee66..580c3fc 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -30338,13 +30338,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 { @@ -30352,6 +30353,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; @@ -30447,6 +30450,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 0000000..9c6c841 --- /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" } |