diff mbox series

[pushed] c++: alias template equivalence and CTAD [PR103852]

Message ID 20220405163004.2099642-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: alias template equivalence and CTAD [PR103852] | expand

Commit Message

Jason Merrill April 5, 2022, 4:30 p.m. UTC
I had been thinking about DR1286 "equivalence" as meaning generally
interchangeable, but looking back at the proposed resolution in the context
of this PR, I see that it's just about use as a template argument.  So let's
give a pedwarn if we look through a renaming alias.

Tested x86_64-pc-linux-gnu, applying to trunk.

	PR c++/103852
	DR 1286

gcc/cp/ChangeLog:

	* pt.cc (do_class_deduction): Pedwarn for renaming alias in C++17.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp1z/class-deduction-alias1.C: Expect warning.
---
 gcc/cp/pt.cc                                  | 26 +++++++++++++++----
 .../g++.dg/cpp1z/class-deduction-alias1.C     |  3 ++-
 2 files changed, 23 insertions(+), 6 deletions(-)


base-commit: 1de6612d994ada8edaab18bbc6afd8e9a57413aa
diff mbox series

Patch

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 1f0231f70e6..eeebc4c1ef3 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -29909,8 +29909,6 @@  do_class_deduction (tree ptype, tree tmpl, tree init,
       && CLASS_PLACEHOLDER_TEMPLATE (TREE_TYPE (init)) == tmpl)
     return cp_build_qualified_type (TREE_TYPE (init), cp_type_quals (ptype));
 
-  /* Look through alias templates that just rename another template.  */
-  tmpl = get_underlying_template (tmpl);
   if (!ctad_template_p (tmpl))
     {
       if (complain & tf_error)
@@ -29920,15 +29918,33 @@  do_class_deduction (tree ptype, tree tmpl, tree init,
   else if (cxx_dialect < cxx20 && DECL_ALIAS_TEMPLATE_P (tmpl))
     {
       if (complain & tf_error)
-	error ("alias template deduction only available "
-	       "with %<-std=c++20%> or %<-std=gnu++20%>");
-      return error_mark_node;
+	{
+	  /* Be permissive with equivalent alias templates.  */
+	  tree u = get_underlying_template (tmpl);
+	  diagnostic_t dk = (u == tmpl) ? DK_ERROR : DK_PEDWARN;
+	  bool complained
+	    = emit_diagnostic (dk, input_location, 0,
+			       "alias template deduction only available "
+			       "with %<-std=c++20%> or %<-std=gnu++20%>");
+	  if (u == tmpl)
+	    return error_mark_node;
+	  else if (complained)
+	    {
+	      inform (input_location, "use %qD directly instead", u);
+	      tmpl = u;
+	    }
+	}
+      else
+	return error_mark_node;
     }
 
   /* Wait until the initializer is non-dependent.  */
   if (type_dependent_expression_p (init))
     return ptype;
 
+  /* Don't bother with the alias rules for an equivalent template.  */
+  tmpl = get_underlying_template (tmpl);
+
   tree type = TREE_TYPE (tmpl);
 
   bool try_list_ctor = false;
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C
index 1ec90b58e3a..ffa5f2bad94 100644
--- a/gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C
@@ -1,5 +1,6 @@ 
 // PR c++/103852
 // { dg-do compile { target c++17 } }
+// { dg-options "" }
 
 template <class T> struct b{};
 template <class T, class T1 = b<T>>
@@ -10,7 +11,7 @@  struct s
 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
+ss tt(1);   // { dg-warning "alias template deduction" "" { target c++17_only } }
 
 template <class T, class T1 = T>
 using ss2 = s<T, T1>;	     // different default arg makes it non-equivalent