Fix handling of non-dependent calls with default template args.
authorJason Merrill <jason@redhat.com>
Thu, 19 May 2016 19:20:40 +0000 (15:20 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 19 May 2016 19:20:40 +0000 (15:20 -0400)
PR c++/10200
* pt.c (fn_type_unification): Add outer template args if needed.
(type_unification_real): Handle getting full args.

From-SVN: r236486

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

index 70dbcb3e7159d0f73f326ff758ba8afce77d796a..5c38aaf9b57af2bb8d2bfc6b7e3fcb7e1ccb32c7 100644 (file)
@@ -1,3 +1,9 @@
+2016-05-19  Jason Merrill  <jason@redhat.com>
+
+       PR c++/10200
+       * pt.c (fn_type_unification): Add outer template args if needed.
+       (type_unification_real): Handle getting full args.
+
 2016-05-19  David Malcolm  <dmalcolm@redhat.com>
 
        PR c++/71184
index fde3091951747e7f9ed4c7195b41baa71ade989a..39085927e8602bb6d33daf362de651eac3ad0cc7 100644 (file)
@@ -17578,6 +17578,13 @@ fn_type_unification (tree fn,
   tree tinst;
   tree r = error_mark_node;
 
+  tree full_targs = targs;
+  if (TMPL_ARGS_DEPTH (targs)
+      < TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (fn)))
+    full_targs = (add_outermost_template_args
+                 (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (fn)),
+                  targs));
+
   if (decltype_p)
     complain |= tf_decltype;
 
@@ -17623,6 +17630,14 @@ fn_type_unification (tree fn,
       location_t loc = input_location;
       bool incomplete = false;
 
+      if (explicit_targs == error_mark_node)
+       goto fail;
+
+      if (TMPL_ARGS_DEPTH (explicit_targs)
+         < TMPL_ARGS_DEPTH (full_targs))
+       explicit_targs = add_outermost_template_args (full_targs,
+                                                     explicit_targs);
+
       /* Adjust any explicit template arguments before entering the
         substitution context.  */
       explicit_targs
@@ -17702,6 +17717,7 @@ fn_type_unification (tree fn,
        goto fail;
 
       /* Place the explicitly specified arguments in TARGS.  */
+      explicit_targs = INNERMOST_TEMPLATE_ARGS (explicit_targs);
       for (i = NUM_TMPL_ARGS (explicit_targs); i--;)
        TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i);
     }
@@ -17751,7 +17767,7 @@ fn_type_unification (tree fn,
   checks = NULL;
 
   ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
-                              targs, parms, args, nargs, /*subr=*/0,
+                              full_targs, parms, args, nargs, /*subr=*/0,
                               strict, flags, &checks, explain_p);
   if (!explain_p)
     pop_tinst_level ();
@@ -18247,7 +18263,7 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
 
 static int
 type_unification_real (tree tparms,
-                      tree targs,
+                      tree full_targs,
                       tree xparms,
                       const tree *xargs,
                       unsigned int xnargs,
@@ -18270,6 +18286,8 @@ type_unification_real (tree tparms,
   gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
   gcc_assert (ntparms > 0);
 
+  tree targs = INNERMOST_TEMPLATE_ARGS (full_targs);
+
   /* Reset the number of non-defaulted template arguments contained
      in TARGS.  */
   NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs) = NULL_TREE;
@@ -18304,7 +18322,7 @@ type_unification_real (tree tparms,
       arg = args[ia];
       ++ia;
 
-      if (unify_one_argument (tparms, targs, parm, arg, subr, strict,
+      if (unify_one_argument (tparms, full_targs, parm, arg, subr, strict,
                              explain_p))
        return 1;
     }
@@ -18324,7 +18342,7 @@ type_unification_real (tree tparms,
 
       /* Copy the parameter into parmvec.  */
       TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms);
-      if (unify_pack_expansion (tparms, targs, parmvec, argvec, strict,
+      if (unify_pack_expansion (tparms, full_targs, parmvec, argvec, strict,
                                 /*subr=*/subr, explain_p))
         return 1;
 
@@ -18485,8 +18503,8 @@ type_unification_real (tree tparms,
          location_t save_loc = input_location;
          if (DECL_P (parm))
            input_location = DECL_SOURCE_LOCATION (parm);
-         arg = tsubst_template_arg (arg, targs, complain, NULL_TREE);
-         arg = convert_template_argument (parm, arg, targs, complain,
+         arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE);
+         arg = convert_template_argument (parm, arg, full_targs, complain,
                                           i, NULL_TREE);
          input_location = save_loc;
          *checks = get_deferred_access_checks ();
diff --git a/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg6.C b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg6.C
new file mode 100644 (file)
index 0000000..1e0dc54
--- /dev/null
@@ -0,0 +1,7 @@
+// { dg-do compile { target c++11 } }
+
+template <class T>
+struct A {
+  template <int I = 42, int J = (T)42> int f() { return I; }
+  template <int I = 42> int g() { return f(); }
+};