From: jason Date: Fri, 4 Mar 2016 01:45:43 +0000 (+0000) Subject: PR c++/67164 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9866098d5bf35f39c94d549475b6cf241c471048;p=thirdparty%2Fgcc.git PR c++/67164 * pt.c (copy_template_args): New. (tsubst_pack_expansion): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233954 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6eae6fd91971..e68382c3440c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-03-03 Jason Merrill + PR c++/67164 + * pt.c (copy_template_args): New. + (tsubst_pack_expansion): Use it. + * call.c (build_aggr_conv): Use get_nsdmi. PR c++/51406 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b3681be9e438..c5b92013830b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -178,6 +178,7 @@ static int check_cv_quals_for_unify (int, tree, tree); static void template_parm_level_and_index (tree, int*, int*); static int unify_pack_expansion (tree, tree, tree, tree, unification_kind_t, bool, bool); +static tree copy_template_args (tree); static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_parms (tree, tree, tsubst_flags_t); @@ -11037,11 +11038,12 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, /* For each argument in each argument pack, substitute into the pattern. */ result = make_tree_vec (len); + tree elem_args = copy_template_args (args); for (i = 0; i < len; ++i) { t = gen_elem_of_pack_expansion_instantiation (pattern, packs, i, - args, complain, + elem_args, complain, in_decl); TREE_VEC_ELT (result, i) = t; if (t == error_mark_node) @@ -11136,6 +11138,32 @@ make_argument_pack (tree vec) return pack; } +/* Return an exact copy of template args T that can be modified + independently. */ + +static tree +copy_template_args (tree t) +{ + if (t == error_mark_node) + return t; + + int len = TREE_VEC_LENGTH (t); + tree new_vec = make_tree_vec (len); + + for (int i = 0; i < len; ++i) + { + tree elt = TREE_VEC_ELT (t, i); + if (elt && TREE_CODE (elt) == TREE_VEC) + elt = copy_template_args (elt); + TREE_VEC_ELT (new_vec, i) = elt; + } + + NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_vec) + = NON_DEFAULT_TEMPLATE_ARGS_COUNT (t); + + return new_vec; +} + /* Substitute ARGS into the vector or list of template arguments T. */ static tree diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-tuple2.C b/gcc/testsuite/g++.dg/cpp0x/variadic-tuple2.C new file mode 100644 index 000000000000..43c00e91d564 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-tuple2.C @@ -0,0 +1,29 @@ +// PR c++/67164 +// { dg-do compile { target c++11 } } + +#include + +namespace detail { + template + struct fast_and + : std::is_same, fast_and<(b, true)...>> + { }; +} + +template +struct tuple { + tuple() { } + + template ::value...>::value + >::type> + tuple(Yn&& ...yn) { } + + template ::value...>::value + >::type> + tuple(tuple const& other) { } +}; + +tuple> t{}; +tuple> copy = t;