public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: partial ordering with dependent NTTP type [PR105289]
@ 2022-04-22 18:33 Patrick Palka
  2022-04-22 18:41 ` Patrick Palka
  0 siblings, 1 reply; 7+ messages in thread
From: Patrick Palka @ 2022-04-22 18:33 UTC (permalink / raw)
  To: gcc-patches

Here ever since r11-6483-ge2e2f3f2c9400f we're rejecting and crashing
(respectively) on two testcases that we used to accept in C++17 mode.
Both testcases declare partial specializations for which the primary
template contains an NTTP with dependent type, but the correctness of
these partial specializations is unclear according to PR86193.

This patch restores the previous C++17 behavior for such partial
specializations by restricting the r11-6483 change to just ordinary
deduction as opposed to deduction for sake of partial ordering.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/11?

	PR c++/105289
	PR c++/86193

gcc/cp/ChangeLog:

	* pt.cc (unify) <case TEMPLATE_PARM_INDEX>: Restrict the
	r11-6483 change to just ordinary deduction for function
	templates.  When substituting into the NTTP type the second
	time, use the original type not the substituted type.  Remove
	now unnecessary level check.

gcc/testsuite/ChangeLog:

	* g++.dg/template/partial5.C: Revert r11-6483 change.
	* g++.dg/template/partial-specialization11.C: New test.
	* g++.dg/template/partial-specialization12.C: New test.
---
 gcc/cp/pt.cc                                  | 25 ++++++++++++-------
 .../template/partial-specialization11.C       | 10 ++++++++
 .../template/partial-specialization12.C       | 12 +++++++++
 gcc/testsuite/g++.dg/template/partial5.C      |  2 +-
 4 files changed, 39 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization11.C
 create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization12.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index dde62ee052d..52bd130b7e7 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -24287,8 +24287,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
 	  /* We haven't deduced the type of this parameter yet.  */
 	  if (cxx_dialect >= cxx17
 	      /* We deduce from array bounds in try_array_deduction.  */
-	      && !(strict & UNIFY_ALLOW_INTEGER)
-	      && TEMPLATE_PARM_LEVEL (parm) <= TMPL_ARGS_DEPTH (targs))
+	      && !(strict & UNIFY_ALLOW_INTEGER))
 	    {
 	      /* Deduce it from the non-type argument.  As above, ignore
 		 top-level quals here too.  */
@@ -24296,13 +24295,21 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
 	      RECUR_AND_CHECK_FAILURE (tparms, targs,
 				       tparm, atype,
 				       UNIFY_ALLOW_NONE, explain_p);
-	      /* Now check whether the type of this parameter is still
-		 dependent, and give up if so.  */
-	      ++processing_template_decl;
-	      tparm = tsubst (tparm, targs, tf_none, NULL_TREE);
-	      --processing_template_decl;
-	      if (uses_template_parms (tparm))
-		return unify_success (explain_p);
+	      if (!processing_template_decl
+		  && TPARMS_PRIMARY_TEMPLATE (tparms)
+		  && DECL_FUNCTION_TEMPLATE_P (TPARMS_PRIMARY_TEMPLATE
+					       (tparms)))
+		{
+		  /* If the NTTP's type uses still-undeduced template
+		     parameters, then don't unify it now.  This gives
+		     type_unification_real a chance to retry deduction
+		     with default template arguments substituted in.  */
+		  ++processing_template_decl;
+		  tparm = tsubst (TREE_TYPE (parm), targs, tf_none, NULL_TREE);
+		  --processing_template_decl;
+		  if (uses_template_parms (tparm))
+		    return unify_success (explain_p);
+		}
 	    }
 	  else
 	    /* Try again later.  */
diff --git a/gcc/testsuite/g++.dg/template/partial-specialization11.C b/gcc/testsuite/g++.dg/template/partial-specialization11.C
new file mode 100644
index 00000000000..20da407d422
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/partial-specialization11.C
@@ -0,0 +1,10 @@
+// PR c++/105289
+
+template<class T> struct value_type;
+
+template<class T, typename value_type<T>::type V>
+struct push_front_vlist;
+
+template<class T, int V>
+struct push_front_vlist<T*, V> { };
+// { dg-error "not more specialized" "PR86193" { target c++14_down } .-1 }
diff --git a/gcc/testsuite/g++.dg/template/partial-specialization12.C b/gcc/testsuite/g++.dg/template/partial-specialization12.C
new file mode 100644
index 00000000000..d70f7592790
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/partial-specialization12.C
@@ -0,0 +1,12 @@
+// PR c++/105289
+// { dg-do compile { target c++11 } }
+
+template<class T>
+struct value_type;
+
+template <class List, typename value_type<List>::type Element>
+struct push_front_vlist;
+
+template <template <class X, X...> class XList, class T, T Arg, T... Vs>
+struct push_front_vlist<XList<T, Vs...>, Arg> { };
+// { dg-error "not more specialized" "PR86193" { target c++14_down } .-1 }
diff --git a/gcc/testsuite/g++.dg/template/partial5.C b/gcc/testsuite/g++.dg/template/partial5.C
index 037f684cbd2..7492632f39b 100644
--- a/gcc/testsuite/g++.dg/template/partial5.C
+++ b/gcc/testsuite/g++.dg/template/partial5.C
@@ -14,7 +14,7 @@ template<typename T, typename T::foo V>
 struct Y { };
 
 template<typename T, typename U, U v>
-struct Y<T, v> { }; // { dg-error "" }
+struct Y<T, v> { }; // { dg-error "" "PR86193" { target c++14_down } }
 
 
 template<typename T, T V>
-- 
2.36.0.rc2.10.g1ac7422e39


^ permalink raw reply	[flat|nested] 7+ messages in thread
* [PATCH] c++: partial ordering with dependent NTTP type [PR105289]
@ 2022-04-22 17:50 Patrick Palka
  2022-04-22 19:27 ` Patrick Palka
  0 siblings, 1 reply; 7+ messages in thread
From: Patrick Palka @ 2022-04-22 17:50 UTC (permalink / raw)
  To: gcc-patches

Here ever since r11-6483-ge2e2f3f2c9400f we're rejecting and crashing
(respectively) on two testcases that we used to accept in C++17 mode.
Both testcases declare partial specializations for which the primary
template contains an NTTP with dependent type, but the correctness of
these partial specializations is unclear according to PR86193.

This patch restores the previous C++17 behavior for such partial
specializations by restricting the r11-6483 change to just ordinary
deduction as opposed to deduction for sake of partial ordering.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/11?

	PR c++/105289
	PR c++/86193

gcc/cp/ChangeLog:

	* pt.cc (unify) <case TEMPLATE_PARM_INDEX>: Restrict the
	r11-6483 change to just ordinary deduction for function
	templates.  When substituting into the NTTP type the second
	time, use the original type not the substituted type.  Remove
	now unnecessary level check.

gcc/testsuite/ChangeLog:

	* g++.dg/template/partial5.C: Revert r11-6483 change.
	* g++.dg/template/partial-specialization11.C: New test.
	* g++.dg/template/partial-specialization12.C: New test.
---
 gcc/cp/pt.cc                                  | 25 ++++++++++++-------
 .../template/partial-specialization11.C       | 10 ++++++++
 .../template/partial-specialization12.C       | 12 +++++++++
 gcc/testsuite/g++.dg/template/partial5.C      |  2 +-
 4 files changed, 39 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization11.C
 create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization12.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index dde62ee052d..52bd130b7e7 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -24287,8 +24287,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
 	  /* We haven't deduced the type of this parameter yet.  */
 	  if (cxx_dialect >= cxx17
 	      /* We deduce from array bounds in try_array_deduction.  */
-	      && !(strict & UNIFY_ALLOW_INTEGER)
-	      && TEMPLATE_PARM_LEVEL (parm) <= TMPL_ARGS_DEPTH (targs))
+	      && !(strict & UNIFY_ALLOW_INTEGER))
 	    {
 	      /* Deduce it from the non-type argument.  As above, ignore
 		 top-level quals here too.  */
@@ -24296,13 +24295,21 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
 	      RECUR_AND_CHECK_FAILURE (tparms, targs,
 				       tparm, atype,
 				       UNIFY_ALLOW_NONE, explain_p);
-	      /* Now check whether the type of this parameter is still
-		 dependent, and give up if so.  */
-	      ++processing_template_decl;
-	      tparm = tsubst (tparm, targs, tf_none, NULL_TREE);
-	      --processing_template_decl;
-	      if (uses_template_parms (tparm))
-		return unify_success (explain_p);
+	      if (!processing_template_decl
+		  && TPARMS_PRIMARY_TEMPLATE (tparms)
+		  && DECL_FUNCTION_TEMPLATE_P (TPARMS_PRIMARY_TEMPLATE
+					       (tparms)))
+		{
+		  /* If the NTTP's type uses still-undeduced template
+		     parameters, then don't unify it now.  This gives
+		     type_unification_real a chance to retry deduction
+		     with default template arguments substituted in.  */
+		  ++processing_template_decl;
+		  tparm = tsubst (TREE_TYPE (parm), targs, tf_none, NULL_TREE);
+		  --processing_template_decl;
+		  if (uses_template_parms (tparm))
+		    return unify_success (explain_p);
+		}
 	    }
 	  else
 	    /* Try again later.  */
diff --git a/gcc/testsuite/g++.dg/template/partial-specialization11.C b/gcc/testsuite/g++.dg/template/partial-specialization11.C
new file mode 100644
index 00000000000..20da407d422
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/partial-specialization11.C
@@ -0,0 +1,10 @@
+// PR c++/105289
+
+template<class T> struct value_type;
+
+template<class T, typename value_type<T>::type V>
+struct push_front_vlist;
+
+template<class T, int V>
+struct push_front_vlist<T*, V> { };
+// { dg-error "not more specialized" "PR86193" { target c++14_down } .-1 }
diff --git a/gcc/testsuite/g++.dg/template/partial-specialization12.C b/gcc/testsuite/g++.dg/template/partial-specialization12.C
new file mode 100644
index 00000000000..d70f7592790
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/partial-specialization12.C
@@ -0,0 +1,12 @@
+// PR c++/105289
+// { dg-do compile { target c++11 } }
+
+template<class T>
+struct value_type;
+
+template <class List, typename value_type<List>::type Element>
+struct push_front_vlist;
+
+template <template <class X, X...> class XList, class T, T Arg, T... Vs>
+struct push_front_vlist<XList<T, Vs...>, Arg> { };
+// { dg-error "not more specialized" "PR86193" { target c++14_down } .-1 }
diff --git a/gcc/testsuite/g++.dg/template/partial5.C b/gcc/testsuite/g++.dg/template/partial5.C
index 037f684cbd2..7492632f39b 100644
--- a/gcc/testsuite/g++.dg/template/partial5.C
+++ b/gcc/testsuite/g++.dg/template/partial5.C
@@ -14,7 +14,7 @@ template<typename T, typename T::foo V>
 struct Y { };
 
 template<typename T, typename U, U v>
-struct Y<T, v> { }; // { dg-error "" }
+struct Y<T, v> { }; // { dg-error "" "PR86193" { target c++14_down } }
 
 
 template<typename T, T V>
-- 
2.36.0.rc2.10.g1ac7422e39


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-04-25 21:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-22 18:33 [PATCH] c++: partial ordering with dependent NTTP type [PR105289] Patrick Palka
2022-04-22 18:41 ` Patrick Palka
  -- strict thread matches above, loose matches on Subject: below --
2022-04-22 17:50 Patrick Palka
2022-04-22 19:27 ` Patrick Palka
2022-04-25 15:12   ` Jason Merrill
2022-04-25 18:10     ` Patrick Palka
2022-04-25 21:53       ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).