diff options
author | Jason Merrill <jason@redhat.com> | 2022-04-01 15:55:21 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2022-04-04 10:43:33 -0400 |
commit | a11f204e5a30d1dfd2508e3f3014509a0342f604 (patch) | |
tree | 94522b48491e007b1f98a227ee44cb4ec21287d6 | |
parent | 2f0610acbc056052a108e4a46911fc21d0dca2ab (diff) | |
download | gcc-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.
-rw-r--r-- | gcc/cp/pt.cc | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286a.C | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C | 17 |
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 } } |