]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/53862 ([C++11] sorry, unimplemented: use of 'type_pack_expansion' in template)
authorJason Merrill <jason@redhat.com>
Thu, 29 Nov 2012 21:58:16 +0000 (16:58 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 29 Nov 2012 21:58:16 +0000 (16:58 -0500)
PR c++/53862
* pt.c (tsubst_arg_types): Add "end" parameter.
(check_undeduced_parms): Use it.

From-SVN: r193970

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

index e2642a9c8f3de7d3951998e0c562d96efa3a66da..a6b69cbe81a4e068302e9ca485b125f56d8904a1 100644 (file)
@@ -1,5 +1,9 @@
 2012-11-29  Jason Merrill  <jason@redhat.com>
 
+       PR c++/53862
+       * pt.c (tsubst_arg_types): Add "end" parameter.
+       (check_undeduced_parms): Use it.
+
        PR c++/51662
        * method.c (process_subob_fn): Increment function_depth around call to
        instantiate_decl.
index 42e8a5972be74fefe4b8d78ca63bfd5394c8e9ea..4b7dd2f725dd195f6428f56e96fe5a46c241290e 100644 (file)
@@ -161,7 +161,7 @@ static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
 static void regenerate_decl_from_template (tree, tree);
 static tree most_specialized_class (tree, tree, tsubst_flags_t);
 static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
-static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree);
 static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
 static bool check_specialization_scope (void);
 static tree process_partial_specialization (tree);
@@ -10186,11 +10186,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
   return r;
 }
 
-/* Substitute into the ARG_TYPES of a function type.  */
+/* Substitute into the ARG_TYPES of a function type.
+   If END is a TREE_CHAIN, leave it and any following types
+   un-substituted.  */
 
 static tree
 tsubst_arg_types (tree arg_types,
                  tree args,
+                 tree end,
                  tsubst_flags_t complain,
                  tree in_decl)
 {
@@ -10200,11 +10203,11 @@ tsubst_arg_types (tree arg_types,
   tree expanded_args = NULL_TREE;
   tree default_arg;
 
-  if (!arg_types || arg_types == void_list_node)
+  if (!arg_types || arg_types == void_list_node || arg_types == end)
     return arg_types;
 
   remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types),
-                                         args, complain, in_decl);
+                                         args, end, complain, in_decl);
   if (remaining_arg_types == error_mark_node)
     return error_mark_node;
 
@@ -10329,7 +10332,7 @@ tsubst_function_type (tree t,
     }
 
   /* Substitute the argument types.  */
-  arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args,
+  arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, NULL_TREE,
                                complain, in_decl);
   if (arg_types == error_mark_node)
     return error_mark_node;
@@ -15910,12 +15913,9 @@ check_undeduced_parms (tree targs, tree args, tree end)
       }
   if (found)
     {
-      for (; args != end; args = TREE_CHAIN (args))
-       {
-         tree substed = tsubst (TREE_VALUE (args), targs, tf_none, NULL_TREE);
-         if (substed == error_mark_node)
-           return true;
-       }
+      tree substed = tsubst_arg_types (args, targs, end, tf_none, NULL_TREE);
+      if (substed == error_mark_node)
+       return true;
     }
   return false;
 }
index 6a1e3e4a1338737948dfeab843fd55769db79d8d..b19b2881f44f40aeb07effe616946a974084b8da 100644 (file)
@@ -1,3 +1,8 @@
+2012-11-29  Jason Merrill  <jason@redhat.com>
+
+       PR c++/53862
+       * g++.dg/cpp0x/variadic134.C: New.
+
 2012-11-24  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/55314
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic134.C b/gcc/testsuite/g++.dg/cpp0x/variadic134.C
new file mode 100644 (file)
index 0000000..b7ec40c
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/53862
+// { dg-options "-std=c++0x" }
+
+typedef unsigned long size_t;
+
+template<typename> struct is_scalar { static const bool value = true; };
+template<bool, typename T> struct enable_if { typedef T type; };
+
+template <size_t N, typename... Args>
+void f(Args...) {}
+
+template <size_t N, typename T, typename... Args>
+typename enable_if<is_scalar<T>::value, void>::type f(T, Args...) {}
+
+int main() {
+    f<1>(1);
+}