diff options
author | Jason Merrill <jason@redhat.com> | 2016-03-03 20:45:43 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-03-03 20:45:43 -0500 |
commit | 264fd1424e7e198bc071f832a300cef9b0b0fac0 (patch) | |
tree | 312da67ba3486fd61c2193485ca841891809c8f9 /gcc | |
parent | 6fdb0d67d06dea7632c36d396031b7cb41d74562 (diff) | |
download | gcc-264fd1424e7e198bc071f832a300cef9b0b0fac0.zip gcc-264fd1424e7e198bc071f832a300cef9b0b0fac0.tar.gz gcc-264fd1424e7e198bc071f832a300cef9b0b0fac0.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic-tuple2.C | 29 |
3 files changed, 62 insertions, 1 deletions
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 <jason@redhat.com> + 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 <type_traits> + +namespace detail { + template <bool ...b> + struct fast_and + : std::is_same<fast_and<b...>, fast_and<(b, true)...>> + { }; +} + +template <typename ...Xn> +struct tuple { + tuple() { } + + template <typename ...Yn, typename = typename std::enable_if< + detail::fast_and<std::is_constructible<Xn, Yn&&>::value...>::value + >::type> + tuple(Yn&& ...yn) { } + + template <typename ...Yn, typename = typename std::enable_if< + detail::fast_and<std::is_constructible<Xn, Yn const&>::value...>::value + >::type> + tuple(tuple<Yn...> const& other) { } +}; + +tuple<tuple<>> t{}; +tuple<tuple<>> copy = t; |