@@ -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;
}
@@ -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;
new file mode 100644
@@ -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 } }