From 264fd1424e7e198bc071f832a300cef9b0b0fac0 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 3 Mar 2016 20:45:43 -0500 Subject: [PATCH] =?utf8?q?re=20PR=20c++/67164=20(ICE:=20tree=20check:=20ex?= =?utf8?q?pected=20class=20=E2=80=98expression=E2=80=99,=20have=20?= =?utf8?q?=E2=80=98exceptional=E2=80=99=20(argument=5Fpack=5Fselect)=20in?= =?utf8?q?=20tree=5Foperand=5Fcheck,=20at=20tree.h:3356)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit PR c++/67164 * pt.c (copy_template_args): New. (tsubst_pack_expansion): Use it. From-SVN: r233954 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/pt.c | 30 +++++++++++++++++++++++++++- gcc/testsuite/g++.dg/cpp0x/variadic-tuple2.C | 29 +++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic-tuple2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6eae6fd..e68382c 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 b3681be..c5b9201 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 0000000..43c00e9 --- /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; -- 2.7.4