Patchwork C++ PATCH for c++/55724 (default template argument and non-type parameter)

login
register
mail settings
Submitter Jason Merrill
Date Dec. 19, 2012, 10:06 p.m.
Message ID <50D23A6C.3050602@redhat.com>
Download mbox | patch
Permalink /patch/207528/
State New
Headers show

Comments

Jason Merrill - Dec. 19, 2012, 10:06 p.m.
My changes to handle incomplete packs ended up splitting the late loop 
in type_unification_real into two loops, one to check whether there are 
any non-type template parameters that still have a dependent type, and 
then another to apply default arguments.  This breaks the testcase in 
55724, which depends on the default argument for a type parameter in 
order to deduce the value of a non-type parameter.  I tried just 
combining the two loops again to see what breaks, and nothing does.

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

Patch

commit c6ea657d938078a53448dbb8b4438d9c94679fb3
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Dec 19 06:15:24 2012 -0500

    	PR c++/55724
    	* pt.c (type_unification_real): Re-combine post-deduction loops.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a21522b..1b3f039 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15333,13 +15333,19 @@  type_unification_real (tree tparms,
 				 ? tf_warning_or_error
 				 : tf_none);
 
-      /* Check to see if we need another pass before we start clearing
-	 ARGUMENT_PACK_INCOMPLETE_P.  */
       for (i = 0; i < ntparms; i++)
 	{
 	  tree targ = TREE_VEC_ELT (targs, i);
 	  tree tparm = TREE_VEC_ELT (tparms, i);
 
+	  /* Clear the "incomplete" flags on all argument packs now so that
+	     substituting them into later default arguments works.  */
+	  if (targ && ARGUMENT_PACK_P (targ))
+            {
+              ARGUMENT_PACK_INCOMPLETE_P (targ) = 0;
+              ARGUMENT_PACK_EXPLICIT_ARGS (targ) = NULL_TREE;
+            }
+
 	  if (targ || tparm == error_mark_node)
 	    continue;
 	  tparm = TREE_VALUE (tparm);
@@ -15352,24 +15358,6 @@  type_unification_real (tree tparms,
 	      && uses_template_parms (TREE_TYPE (tparm))
 	      && !saw_undeduced++)
 	    goto again;
-	}
-
-      for (i = 0; i < ntparms; i++)
-	{
-	  tree targ = TREE_VEC_ELT (targs, i);
-	  tree tparm = TREE_VEC_ELT (tparms, i);
-
-	  /* Clear the "incomplete" flags on all argument packs now so that
-	     substituting them into later default arguments works.  */
-	  if (targ && ARGUMENT_PACK_P (targ))
-            {
-              ARGUMENT_PACK_INCOMPLETE_P (targ) = 0;
-              ARGUMENT_PACK_EXPLICIT_ARGS (targ) = NULL_TREE;
-            }
-
-	  if (targ || tparm == error_mark_node)
-	    continue;
-	  tparm = TREE_VALUE (tparm);
 
 	  /* Core issue #226 (C++0x) [temp.deduct]:
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg4.C b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg4.C
new file mode 100644
index 0000000..0248b60
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg4.C
@@ -0,0 +1,6 @@ 
+// PR c++/55724
+// { dg-options -std=c++11 }
+
+template<int N> struct S {};
+template<typename T = int, T N> void f(S<N>) {}
+int main() { S<1> s; f(s); }