OSDN Git Service

PR c++/38543
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index ea20323..383f0d6 100644 (file)
@@ -1860,6 +1860,7 @@ determine_specialization (tree template_id,
        {
          tree decl_arg_types;
          tree fn_arg_types;
+         tree insttype;
 
          /* In case of explicit specialization, we need to check if
             the number of template headers appearing in the specialization
@@ -1927,7 +1928,8 @@ determine_specialization (tree template_id,
               template <> void f<int>();
             The specialization f<int> is invalid but is not caught
             by get_bindings below.  */
-         if (list_length (fn_arg_types) != list_length (decl_arg_types))
+         if (cxx_dialect < cxx11
+             && list_length (fn_arg_types) != list_length (decl_arg_types))
            continue;
 
          /* Function templates cannot be specializations; there are
@@ -1950,6 +1952,18 @@ determine_specialization (tree template_id,
               specialize TMPL will produce DECL.  */
            continue;
 
+         if (cxx_dialect >= cxx11)
+           {
+             /* Make sure that the deduced arguments actually work.  */
+             insttype = tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE);
+             if (insttype == error_mark_node)
+               continue;
+             fn_arg_types
+               = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (insttype));
+             if (!compparms (fn_arg_types, decl_arg_types))
+               continue;
+           }
+
          /* Save this template, and the arguments deduced.  */
          templates = tree_cons (targs, fn, templates);
        }
@@ -6437,6 +6451,7 @@ convert_template_argument (tree parm,
   is_tmpl_type = 
     ((TREE_CODE (arg) == TEMPLATE_DECL
       && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
+     || (requires_tmpl_type && TREE_CODE (arg) == TYPE_ARGUMENT_PACK)
      || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
      || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
 
@@ -6508,7 +6523,9 @@ convert_template_argument (tree parm,
     {
       if (requires_tmpl_type)
        {
-         if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE)
+         if (template_parameter_pack_p (parm) && ARGUMENT_PACK_P (orig_arg))
+           val = orig_arg;
+         else if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE)
            /* The number of argument required is not known yet.
               Just accept it for now.  */
            val = TREE_TYPE (arg);