aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2023-02-09 12:58:35 -0800
committerJason Merrill <jason@redhat.com>2023-03-09 10:25:46 -0500
commitafe1f0c251d0429069c2414d4f3f14042efc174f (patch)
tree2b40a1943b30ad0d90ecca5a2410343bd0431dc4 /gcc
parent9e6170098d5e7756e85e880f8f4cb18e885a64fd (diff)
downloadgcc-afe1f0c251d0429069c2414d4f3f14042efc174f.zip
gcc-afe1f0c251d0429069c2414d4f3f14042efc174f.tar.gz
gcc-afe1f0c251d0429069c2414d4f3f14042efc174f.tar.bz2
c++: CTAD for less-specialized alias template [PR102529]
The standard was unclear what happens with the transformation of a deduction guide if the initial template argument deduction fails for a reason other than not deducing all the arguments; my implementation assumed that the right thing was to give up on the deduction guide. But in consideration of CWG2664 this week I realized that we get a better result by just continuing with an empty set of deductions, so the alias deduction guide is the same as the original deduction guide plus the deducible constraint. DR 2664 PR c++/102529 gcc/cp/ChangeLog: * pt.cc (alias_ctad_tweaks): Continue after deduction failure. gcc/testsuite/ChangeLog: * g++.dg/DRs/dr2664.C: New test. * g++.dg/cpp2a/class-deduction-alias15.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/pt.cc4
-rw-r--r--gcc/testsuite/g++.dg/DRs/dr2664.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/class-deduction-alias15.C18
3 files changed, 38 insertions, 1 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 8c73ea5..65341c4 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -30072,7 +30072,9 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
tree targs = make_tree_vec (len);
int err = unify (ftparms, targs, ret, utype, UNIFY_ALLOW_NONE, false);
if (err)
- continue;
+ /* CWG2664: Discard any deductions, still build the guide. */
+ for (unsigned i = 0; i < len; ++i)
+ TREE_VEC_ELT (targs, i) = NULL_TREE;
/* The number of parms for f' is the number of parms for A plus
non-deduced parms of f. */
diff --git a/gcc/testsuite/g++.dg/DRs/dr2664.C b/gcc/testsuite/g++.dg/DRs/dr2664.C
new file mode 100644
index 0000000..f6bf8e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr2664.C
@@ -0,0 +1,17 @@
+// CWG 2664
+// { dg-do compile { target c++20 } }
+
+template <class S1, class S2> struct C {
+ C(...);
+};
+
+template<class T1> C(T1) -> C<T1, T1>;
+template<class T1, class T2> C(T1, T2) -> C<T1 *, T2>;
+
+template<class V1, class V2> using A = C<V1, V2>;
+
+C c1{""};
+A a1{""};
+
+C c2{"", 1};
+A a2{"", 1};
diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias15.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias15.C
new file mode 100644
index 0000000..db615fa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias15.C
@@ -0,0 +1,18 @@
+// PR c++/102529
+// { dg-do compile { target c++20 } }
+
+template <typename T>
+struct C {
+ template <typename U>
+ C(U);
+};
+
+template <typename U>
+C(U) -> C<U*>;
+
+template <typename T>
+ requires true
+using A = C<T>;
+
+C ok(1); // ok, a is a C<int*>
+A bad(2); // fails