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.
Tested x86_64-pc-linux-gnu, applying to trunk. 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. --- gcc/cp/pt.cc | 13 +++++++++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286a.C | 16 ++++++++-------- .../g++.dg/cpp1z/class-deduction-alias1.C | 17 +++++++++++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 75ed9a34018..1f0231f70e6 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 1780c9a47b7..fbd63d891d0 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 00000000000..1ec90b58e3a --- /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 } } base-commit: 2f0610acbc056052a108e4a46911fc21d0dca2ab -- 2.27.0