diff mbox series

[pushed] c++: alias-tmpl equivalence and default targs [PR103852]

Message ID 20220404144359.1990724-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: alias-tmpl equivalence and default targs [PR103852] | expand

Commit Message

Jason Merrill April 4, 2022, 2:43 p.m. UTC
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


base-commit: 2f0610acbc056052a108e4a46911fc21d0dca2ab
diff mbox series

Patch

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 } }