aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2022-04-01 15:55:21 -0400
committerJason Merrill <jason@redhat.com>2022-04-04 10:43:33 -0400
commita11f204e5a30d1dfd2508e3f3014509a0342f604 (patch)
tree94522b48491e007b1f98a227ee44cb4ec21287d6 /gcc
parent2f0610acbc056052a108e4a46911fc21d0dca2ab (diff)
downloadgcc-a11f204e5a30d1dfd2508e3f3014509a0342f604.zip
gcc-a11f204e5a30d1dfd2508e3f3014509a0342f604.tar.gz
gcc-a11f204e5a30d1dfd2508e3f3014509a0342f604.tar.bz2
c++: alias-tmpl equivalence and default targs [PR103852]
The suggested resolution for CWG1286, which we implemented, ignores default template arguments, but this PR is an example of why that doesn't make sense: the templates aren't functionally equivalent. PR c++/103852 DR 1286 gcc/cp/ChangeLog: * pt.cc (get_underlying_template): Compare default template args. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alias-decl-dr1286a.C: Default args now matter. * g++.dg/cpp1z/class-deduction-alias1.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/pt.cc13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286a.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C17
3 files changed, 38 insertions, 8 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 75ed9a3..1f0231f 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -6637,6 +6637,18 @@ get_underlying_template (tree tmpl)
if (!comp_template_args (TI_ARGS (tinfo), alias_args))
break;
+ /* Are any default template arguments equivalent? */
+ tree aparms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
+ tree uparms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (underlying));
+ const int nparms = TREE_VEC_LENGTH (aparms);
+ for (int i = 0; i < nparms; ++i)
+ {
+ tree adefarg = TREE_PURPOSE (TREE_VEC_ELT (aparms, i));
+ tree udefarg = TREE_PURPOSE (TREE_VEC_ELT (uparms, i));
+ if (!template_args_equal (adefarg, udefarg))
+ goto top_break;
+ }
+
/* If TMPL adds or changes any constraints, it isn't equivalent. I think
it's appropriate to treat a less-constrained alias as equivalent. */
if (!at_least_as_constrained (underlying, tmpl))
@@ -6645,6 +6657,7 @@ get_underlying_template (tree tmpl)
/* Alias is equivalent. Strip it and repeat. */
tmpl = underlying;
}
+ top_break:;
return tmpl;
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286a.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286a.C
index 1780c9a..fbd63d8 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286a.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286a.C
@@ -11,13 +11,13 @@ template<typename T, typename U = T> struct A;
template<template <class...> class> struct X;
// equivalent to A
-template<typename V, typename W>
+template<typename V, typename W = V>
using B = A<V, W>;
same<X<A>,X<B>> s1;
// not equivalent to A: not all parameters used
-template<typename V, typename W>
+template<typename V, typename W = V>
using C = A<V>;
different<X<A>,X<C>> d1;
@@ -29,32 +29,32 @@ using D = A<V>;
different<X<A>,X<D>> d2;
// not equivalent to A: template-arguments in wrong order
-template<typename V, typename W>
+template<typename V, typename W = V>
using E = A<W, V>;
different<X<A>,X<E>> d3;
-// equivalent to A: default arguments not considered
+// NOT equivalent to A: default arguments now considered
template<typename V, typename W = int>
using F = A<V, W>;
-same<X<A>,X<F>> s2;
+different<X<A>,X<F>> s2;
// equivalent to A and B
-template<typename V, typename W>
+template<typename V, typename W = V>
using G = A<V, W>;
same<X<A>,X<G>> s3;
same<X<B>,X<G>> s3b;
// equivalent to E
-template<typename V, typename W>
+template<typename V, typename W = V>
using H = E<V, W>;
same<X<E>,X<H>> s4;
// not equivalent to A: argument not identifier
-template<typename V, typename W>
+template<typename V, typename W = V>
using I = A<V, typename W::type>;
different<X<A>,X<I>> d4;
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C
new file mode 100644
index 0000000..1ec90b5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C
@@ -0,0 +1,17 @@
+// PR c++/103852
+// { dg-do compile { target c++17 } }
+
+template <class T> struct b{};
+template <class T, class T1 = b<T>>
+struct s
+{
+ s(T);
+};
+s c(100);
+template <class T, class T1 = b<T>>
+using ss = s<T, T1>; // equivalent under proposed resolution of DR 1286
+ss tt(1); // OK
+
+template <class T, class T1 = T>
+using ss2 = s<T, T1>; // different default arg makes it non-equivalent
+ss2 tt2(1); // { dg-error "alias template deduction" "" { target c++17_only } }