OSDN Git Service

PR c++/54437
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 4 Sep 2012 18:49:51 +0000 (18:49 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 4 Sep 2012 18:49:51 +0000 (18:49 +0000)
PR c++/51213
* pt.c (fn_type_unification): Call coerce_template_parms before
entering substitution context.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190946 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/access24.C [new file with mode: 0644]

index c36ed88..47498cb 100644 (file)
@@ -1,3 +1,10 @@
+2012-09-04  Jason Merrill  <jason@redhat.com>
+
+       PR c++/54437
+       PR c++/51213
+       * pt.c (fn_type_unification): Call coerce_template_parms before
+       entering substitution context.
+
 2012-08-31  Paolo Carlini  <paolo.carlini@oracle.com>
            Jason Merrill  <jason@redhat.com>
 
index 4a39427..6f6235c 100644 (file)
@@ -14591,11 +14591,22 @@ fn_type_unification (tree fn,
   static int deduction_depth;
   struct pending_template *old_last_pend = last_pending_template;
   struct tinst_level *old_error_tinst = last_error_tinst_level;
+  tree tparms = DECL_INNERMOST_TEMPLATE_PARMS (fn);
   tree tinst;
   tree r = error_mark_node;
 
-  if (excessive_deduction_depth)
-    return error_mark_node;
+  /* Adjust any explicit template arguments before entering the
+     substitution context.  */
+  if (explicit_targs)
+    {
+      explicit_targs
+       = (coerce_template_parms (tparms, explicit_targs, NULL_TREE,
+                                 complain,
+                                 /*require_all_args=*/false,
+                                 /*use_default_args=*/false));
+      if (explicit_targs == error_mark_node)
+       return error_mark_node;
+    }
 
   /* In C++0x, it's possible to have a function template whose type depends
      on itself recursively.  This is most obvious with decltype, but can also
@@ -14608,6 +14619,8 @@ fn_type_unification (tree fn,
      substitutions back up to the initial one.
 
      This is, of course, not reentrant.  */
+  if (excessive_deduction_depth)
+    return error_mark_node;
   tinst = build_tree_list (fn, targs);
   if (!push_tinst_level (tinst))
     {
@@ -14640,23 +14653,10 @@ fn_type_unification (tree fn,
         specified template argument values.  If a substitution in a
         template parameter or in the function type of the function
         template results in an invalid type, type deduction fails.  */
-      tree tparms = DECL_INNERMOST_TEMPLATE_PARMS (fn);
       int i, len = TREE_VEC_LENGTH (tparms);
       location_t loc = input_location;
-      tree converted_args;
       bool incomplete = false;
 
-      if (explicit_targs == error_mark_node)
-       goto fail;
-
-      converted_args
-       = (coerce_template_parms (tparms, explicit_targs, NULL_TREE,
-                                 complain,
-                                  /*require_all_args=*/false,
-                                  /*use_default_args=*/false));
-      if (converted_args == error_mark_node)
-       goto fail;
-
       /* Substitute the explicit args into the function type.  This is
         necessary so that, for instance, explicitly declared function
         arguments can match null pointed constants.  If we were given
@@ -14667,7 +14667,7 @@ fn_type_unification (tree fn,
         {
           tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
           bool parameter_pack = false;
-         tree targ = TREE_VEC_ELT (converted_args, i);
+         tree targ = TREE_VEC_ELT (explicit_targs, i);
 
           /* Dig out the actual parm.  */
           if (TREE_CODE (parm) == TYPE_DECL
@@ -14705,7 +14705,7 @@ fn_type_unification (tree fn,
 
       processing_template_decl += incomplete;
       input_location = DECL_SOURCE_LOCATION (fn);
-      fntype = tsubst (TREE_TYPE (fn), converted_args,
+      fntype = tsubst (TREE_TYPE (fn), explicit_targs,
                       complain | tf_partial, NULL_TREE);
       input_location = loc;
       processing_template_decl -= incomplete;
@@ -14714,8 +14714,8 @@ fn_type_unification (tree fn,
        goto fail;
 
       /* Place the explicitly specified arguments in TARGS.  */
-      for (i = NUM_TMPL_ARGS (converted_args); i--;)
-       TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (converted_args, i);
+      for (i = NUM_TMPL_ARGS (explicit_targs); i--;)
+       TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i);
     }
 
   /* Never do unification on the 'this' parameter.  */
index b7354f4..1c0bde0 100644 (file)
@@ -1,3 +1,8 @@
+2012-09-04  Jason Merrill  <jason@redhat.com>
+
+       PR c++/54437
+       * g++.dg/template/access24.C: New.
+
 2012-09-04  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/54458
diff --git a/gcc/testsuite/g++.dg/template/access24.C b/gcc/testsuite/g++.dg/template/access24.C
new file mode 100644 (file)
index 0000000..9f19226
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/54437
+
+template <void (*P)()> void f();
+class A {
+  template <class T> static void g();
+  template <class T> static void h () { f<g<T> >(); }
+  static void i() { h<int>(); }
+};