re PR c++/53862 ([C++11] sorry, unimplemented: use of 'type_pack_expansion' in template)
authorJason Merrill <jason@redhat.com>
Fri, 6 Jul 2012 15:45:10 +0000 (11:45 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 6 Jul 2012 15:45:10 +0000 (11:45 -0400)
PR c++/53862
* pt.c (tsubst_arg_types): Add "end" parameter.
(check_undeduced_parms): Use it.

From-SVN: r189334

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

index 0bd2c77513dac54ecc0a8b00786fb04e696713f4..f40753924450175f4d8fecaa42f483a8973ade93 100644 (file)
@@ -1,5 +1,9 @@
 2012-07-06  Jason Merrill  <jason@redhat.com>
 
+       PR c++/53862
+       * pt.c (tsubst_arg_types): Add "end" parameter.
+       (check_undeduced_parms): Use it.
+
        * cp-tree.h (DECL_DECLARES_TYPE_P): Check DECL_TYPE_TEMPLATE_P.
 
        PR c++/53858
index df5d1f68b862db57769e352ddad1ea8a5bd2d26a..72b0c4f18b219c0f74abc8ca8a1f46e0aca28d75 100644 (file)
@@ -171,7 +171,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);
@@ -10500,11 +10500,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)
 {
@@ -10514,11 +10517,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;
 
@@ -10643,7 +10646,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;
@@ -16757,12 +16760,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 18187f1a60daa1693c1865c8efd3161a72c8e454..0e79dc33fb757cf4a3375945f8ba0eb9cb45726b 100644 (file)
@@ -1,5 +1,8 @@
 2012-07-06  Jason Merrill  <jason@redhat.com>
 
+       PR c++/53862
+       * g++.dg/cpp0x/variadic134.C: New.
+
        PR c++/53858
        * g++.dg/cpp0x/alias-decl-20.C: New.
 
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..d4181b0
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/53862
+// { dg-do compile { target c++11 } }
+
+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);
+}