diff mbox

[C++] c++/78701 ICE in default arg unification

Message ID e828be51-61b5-8eb5-ba47-269e64bfadcf@acm.org
State New
Headers show

Commit Message

Nathan Sidwell Dec. 14, 2016, 2:05 p.m. UTC
This patch fixes 78701.  The problematic case with a non-type template 
arg whose default value is dependent on a previous non-type arg that 
failed to be deduced on the first iteration of the loop in 
type_unification_real.

Just before the tsubst_template_arg we've already done:

	  if (TREE_CODE (parm) == PARM_DECL
	      && uses_template_parms (TREE_TYPE (parm))
	      && saw_undeduced < 2)
	    continue;

to check the type of the arg is deduced.  This patch adds the equivalent 
check just after tsubsting, to see if we managed to get all the template 
parms replaced.  I wasn't sure if it should check for PARM_DECL, perhaps 
convert_template_argument can cope with the case of a non-subst template 
parm, so checking would save a call to uses_template_parms in the 
type-parm case?

Unfortunately because at this point we've pushed some state, we can't 
simply 'continue'.  Hence I chose to set arg to NULL and check it later.

The deleted continue is the last statement of the loop, hence deleted.

ok?

nathan
-- 
Nathan Sidwell

Comments

Jason Merrill Dec. 14, 2016, 4:33 p.m. UTC | #1
OK.

On Wed, Dec 14, 2016 at 9:05 AM, Nathan Sidwell <nathan@acm.org> wrote:
> This patch fixes 78701.  The problematic case with a non-type template arg

> whose default value is dependent on a previous non-type arg that failed to

> be deduced on the first iteration of the loop in type_unification_real.

>

> Just before the tsubst_template_arg we've already done:

>

>           if (TREE_CODE (parm) == PARM_DECL

>               && uses_template_parms (TREE_TYPE (parm))

>               && saw_undeduced < 2)

>             continue;

>

> to check the type of the arg is deduced.  This patch adds the equivalent

> check just after tsubsting, to see if we managed to get all the template

> parms replaced.  I wasn't sure if it should check for PARM_DECL, perhaps

> convert_template_argument can cope with the case of a non-subst template

> parm, so checking would save a call to uses_template_parms in the type-parm

> case?

>

> Unfortunately because at this point we've pushed some state, we can't simply

> 'continue'.  Hence I chose to set arg to NULL and check it later.

>

> The deleted continue is the last statement of the loop, hence deleted.

>

> ok?

>

> nathan

> --

> Nathan Sidwell
diff mbox

Patch

2016-12-14  Nathan Sidwell  <nathan@acm.org>

	PR c++/78701
	* pt.c (type_unification_real): Check tsubst arg doesn't have
	remaining template parms before converting it.

	PR c++/78701
	* g++.dg/cpp0x/pr78701.C: New.

Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 243580)
+++ cp/pt.c	(working copy)
@@ -18987,14 +18987,19 @@  type_unification_real (tree tparms,
 	  if (DECL_P (parm))
 	    input_location = DECL_SOURCE_LOCATION (parm);
 	  arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE);
-	  arg = convert_template_argument (parm, arg, full_targs, complain,
-					   i, NULL_TREE);
+	  if (!uses_template_parms (arg))
+	    arg = convert_template_argument (parm, arg, full_targs, complain,
+					     i, NULL_TREE);
+	  else if (saw_undeduced < 2)
+	    arg = NULL_TREE;
+	  else
+	    arg = error_mark_node;
 	  input_location = save_loc;
 	  *checks = get_deferred_access_checks ();
 	  pop_deferring_access_checks ();
 	  if (arg == error_mark_node)
 	    return 1;
-	  else
+	  else if (arg)
 	    {
 	      TREE_VEC_ELT (targs, i) = arg;
 	      /* The position of the first default template argument,
@@ -19002,7 +19007,6 @@  type_unification_real (tree tparms,
 		 Record that.  */
 	      if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
 		SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
-	      continue;
 	    }
 	}
 
Index: testsuite/g++.dg/cpp0x/pr78701.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr78701.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/pr78701.C	(working copy)
@@ -0,0 +1,9 @@ 
+// PR c++/58707
+// { dg-do compile { target c++11 } }
+
+// ICE during deduction of default parms
+
+template <class T, T N = T(), bool B = N>
+  void f(T x) {}
+
+template void f<int> (int);