From: Jason Merrill Date: Fri, 4 Mar 2016 01:45:43 +0000 (-0500) Subject: re PR c++/67164 (ICE: tree check: expected class ‘expression’, have ‘exceptional... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=264fd1424e7e198bc071f832a300cef9b0b0fac0;p=gcc.git re PR c++/67164 (ICE: tree check: expected class ‘expression’, have ‘exceptional’ (argument_pack_select) in tree_operand_check, at tree.h:3356) PR c++/67164 * pt.c (copy_template_args): New. (tsubst_pack_expansion): Use it. From-SVN: r233954 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6eae6fd9197..e68382c3440 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 b3681be9e43..c5b92013830 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 00000000000..43c00e91d56 --- /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;