From patchwork Fri Jul 6 15:42:59 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: C++ PATCH for c++/53862 (rejects-valid variadic templates) Date: Fri, 06 Jul 2012 05:42:59 -0000 From: Jason Merrill X-Patchwork-Id: 169485 Message-Id: <4FF70783.2020107@redhat.com> To: gcc-patches List tsubst doesn't handle pack expansions directly; any place where a pack expansion is valid needs to test for them and call tsubst_pack_expansion. Here, the code for testing whether a non-deduced template argument is relevant to the argument types was failing to do so. Conveniently, we already have a tsubst_arg_types function, so we can just call it. Tested x86_64-pc-linux-gnu, applying to trunk. commit 6c2eeaf17d04ff248f69f7ed54f6d1905a759048 Author: Jason Merrill Date: Fri Jul 6 10:25:16 2012 -0400 PR c++/53862 * pt.c (tsubst_arg_types): Add "end" parameter. (check_undeduced_parms): Use it. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index df5d1f6..72b0c4f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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; } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic134.C b/gcc/testsuite/g++.dg/cpp0x/variadic134.C new file mode 100644 index 0000000..d4181b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic134.C @@ -0,0 +1,17 @@ +// PR c++/53862 +// { dg-do compile { target c++11 } } + +typedef unsigned long size_t; + +template struct is_scalar { static const bool value = true; }; +template struct enable_if { typedef T type; }; + +template +void f(Args...) {} + +template +typename enable_if::value, void>::type f(T, Args...) {} + +int main() { + f<1>(1); +}