aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-03-03 20:45:43 -0500
committerJason Merrill <jason@gcc.gnu.org>2016-03-03 20:45:43 -0500
commit264fd1424e7e198bc071f832a300cef9b0b0fac0 (patch)
tree312da67ba3486fd61c2193485ca841891809c8f9 /gcc
parent6fdb0d67d06dea7632c36d396031b7cb41d74562 (diff)
downloadgcc-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/ChangeLog4
-rw-r--r--gcc/cp/pt.c30
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic-tuple2.C29
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;