summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2017-11-03 00:13:06 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2017-11-03 00:13:06 +0000
commitd5f0b3f0bbd96630f8b61536b65d2565e882340d (patch)
treef22b4ba4c1fa6ffe3bfc674bd9be70ccad197c87
parent718afa1acdb7bb247fe69995f3939ed26ab43a42 (diff)
downloadgcc-d5f0b3f0bbd96630f8b61536b65d2565e882340d.tar.gz
re PR c++/81957 (ICE decltype)
/cp 2017-11-02 Paolo Carlini <paolo.carlini@oracle.com> PR c++/81957 * pt.c (make_pack_expansion): Add tsubst_flags_t parameter. (expand_integer_pack, convert_template_argument, coerce_template_parms, gen_elem_of_pack_expansion_instantiation, tsubst_pack_expansion, unify): Adjust calls. * tree.c (cp_build_qualified_type_real): Likewise. * cp-tree.h (make_pack_expansion): Adjust declaration. /testsuite 2017-11-02 Paolo Carlini <paolo.carlini@oracle.com> PR c++/81957 * g++.dg/cpp0x/variadic-crash5.C: New. From-SVN: r254361
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/pt.c31
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic-crash5.C28
6 files changed, 63 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f1dec178920..e7ea5da008a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2017-11-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/81957
+ * pt.c (make_pack_expansion): Add tsubst_flags_t parameter.
+ (expand_integer_pack, convert_template_argument, coerce_template_parms,
+ gen_elem_of_pack_expansion_instantiation, tsubst_pack_expansion,
+ unify): Adjust calls.
+ * tree.c (cp_build_qualified_type_real): Likewise.
+ * cp-tree.h (make_pack_expansion): Adjust declaration.
+
2017-11-02 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (IDENTIFIER_NEWDEL_OP_P): Restore, adjust.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 65f1fae5c5e..874cbcbd2bd 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6482,7 +6482,7 @@ extern bool uses_parameter_packs (tree);
extern bool template_parameter_pack_p (const_tree);
extern bool function_parameter_pack_p (const_tree);
extern bool function_parameter_expanded_from_pack_p (tree, tree);
-extern tree make_pack_expansion (tree);
+extern tree make_pack_expansion (tree, tsubst_flags_t = tf_warning_or_error);
extern bool check_for_bare_parameter_packs (tree);
extern tree build_template_info (tree, tree);
extern tree get_template_info (const_tree);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 629b2dd50ef..710333ddaba 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3435,7 +3435,7 @@ expand_integer_pack (tree call, tree args, tsubst_flags_t complain,
call = copy_node (call);
CALL_EXPR_ARG (call, 0) = hi;
}
- tree ex = make_pack_expansion (call);
+ tree ex = make_pack_expansion (call, complain);
tree vec = make_tree_vec (1);
TREE_VEC_ELT (vec, 0) = ex;
return vec;
@@ -3724,7 +3724,7 @@ uses_parameter_packs (tree t)
EXPR_PACK_EXPANSION, TYPE_PACK_EXPANSION, or TREE_LIST,
respectively. */
tree
-make_pack_expansion (tree arg)
+make_pack_expansion (tree arg, tsubst_flags_t complain)
{
tree result;
tree parameter_packs = NULL_TREE;
@@ -3770,7 +3770,9 @@ make_pack_expansion (tree arg)
if (parameter_packs == NULL_TREE)
{
- error ("base initializer expansion %qT contains no parameter packs", arg);
+ if (complain & tf_error)
+ error ("base initializer expansion %qT contains no parameter packs",
+ arg);
delete ppd.visited;
return error_mark_node;
}
@@ -3834,10 +3836,13 @@ make_pack_expansion (tree arg)
/* Make sure we found some parameter packs. */
if (parameter_packs == NULL_TREE)
{
- if (TYPE_P (arg))
- error ("expansion pattern %qT contains no argument packs", arg);
- else
- error ("expansion pattern %qE contains no argument packs", arg);
+ if (complain & tf_error)
+ {
+ if (TYPE_P (arg))
+ error ("expansion pattern %qT contains no argument packs", arg);
+ else
+ error ("expansion pattern %qE contains no argument packs", arg);
+ }
return error_mark_node;
}
PACK_EXPANSION_PARAMETER_PACKS (result) = parameter_packs;
@@ -7694,7 +7699,7 @@ convert_template_argument (tree parm,
if (DECL_TEMPLATE_TEMPLATE_PARM_P (val))
val = TREE_TYPE (val);
if (TREE_CODE (orig_arg) == TYPE_PACK_EXPANSION)
- val = make_pack_expansion (val);
+ val = make_pack_expansion (val, complain);
}
}
else
@@ -8188,7 +8193,7 @@ coerce_template_parms (tree parms,
else if (TYPE_P (conv) && !TYPE_P (pattern))
/* Recover from missing typename. */
TREE_VEC_ELT (inner_args, arg_idx)
- = make_pack_expansion (conv);
+ = make_pack_expansion (conv, complain);
/* We don't know how many args we have yet, just
use the unconverted ones for now. */
@@ -11161,7 +11166,7 @@ gen_elem_of_pack_expansion_instantiation (tree pattern,
the Ith element resulting from the substituting is going to
be a pack expansion as well. */
if (ith_elem_is_expansion)
- t = make_pack_expansion (t);
+ t = make_pack_expansion (t, complain);
return t;
}
@@ -11573,7 +11578,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
/* We got some full packs, but we can't substitute them in until we
have values for all the packs. So remember these until then. */
- t = make_pack_expansion (pattern);
+ t = make_pack_expansion (pattern, complain);
PACK_EXPANSION_EXTRA_ARGS (t) = args;
return t;
}
@@ -11588,7 +11593,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
/*integral_constant_expression_p=*/false);
else
t = tsubst (pattern, args, complain, in_decl);
- t = make_pack_expansion (t);
+ t = make_pack_expansion (t, complain);
return t;
}
@@ -21323,7 +21328,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
if (REFERENCE_REF_P (arg))
arg = TREE_OPERAND (arg, 0);
if (pexp)
- arg = make_pack_expansion (arg);
+ arg = make_pack_expansion (arg, complain);
return unify (tparms, targs, TREE_OPERAND (parm, 0), arg,
strict, explain_p);
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index b7d5f3dc3f5..b63f2ae4c5d 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1208,7 +1208,7 @@ cp_build_qualified_type_real (tree type,
tree t = PACK_EXPANSION_PATTERN (type);
t = cp_build_qualified_type_real (t, type_quals, complain);
- return make_pack_expansion (t);
+ return make_pack_expansion (t, complain);
}
/* A reference or method type shall not be cv-qualified.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8bf7b55b4dc..6e2abdd9e17 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-11-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/81957
+ * g++.dg/cpp0x/variadic-crash5.C: New.
+
2017-11-02 Steve Ellcey <sellcey@cavium.com>
PR target/79868
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-crash5.C b/gcc/testsuite/g++.dg/cpp0x/variadic-crash5.C
new file mode 100644
index 00000000000..6866f39975a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-crash5.C
@@ -0,0 +1,28 @@
+// PR c++/81957
+// { dg-do compile { target c++11 } }
+
+template <class T, T v>
+struct integral_constant { };
+
+struct f {
+ template<bool b, typename Int>
+ void operator()(integral_constant<bool,b>, Int i) {
+ }
+};
+
+template<bool...Bs, typename F, typename ...T>
+auto dispatch(F f, T...t) -> decltype(f(integral_constant<bool,Bs>()..., t...)) {
+ return f(integral_constant<bool,Bs>()..., t...);
+}
+
+template<bool...Bs, typename F, typename ...T>
+auto dispatch(F f, bool b, T...t) -> decltype(dispatch<Bs..., true>(f, t...)) {
+ if (b)
+ return dispatch<Bs..., true>(f, t...);
+ else
+ return dispatch<Bs..., false>(f, t...);
+}
+
+int main() {
+ dispatch(f(), true, 5);
+}