Commit 8ba8c375 by Jason Merrill Committed by Jason Merrill

re PR c++/69889 (ICE: in assign_temp, at function.c:961)

	PR c++/69889

	* cp-tree.h (AGGR_INIT_FROM_THUNK_P): New.
	* tree.c (build_aggr_init_expr): Set it.
	* semantics.c (simplify_aggr_init_expr): Check it.
	* cp-gimplify.c (cp_genericize_r): Don't walk into
	a call/aggr_init from a thunk.

From-SVN: r233733
parent 1569de0f
2016-02-25 Jason Merrill <jason@redhat.com> 2016-02-25 Jason Merrill <jason@redhat.com>
PR c++/69889
* cp-tree.h (AGGR_INIT_FROM_THUNK_P): New.
* tree.c (build_aggr_init_expr): Set it.
* semantics.c (simplify_aggr_init_expr): Check it.
* cp-gimplify.c (cp_genericize_r): Don't walk into
a call/aggr_init from a thunk.
PR c++/69842 PR c++/69842
* method.c (forward_parm): Handle parameter packs. * method.c (forward_parm): Handle parameter packs.
* lambda.c (maybe_add_lambda_conv_op): Use it for them. * lambda.c (maybe_add_lambda_conv_op): Use it for them.
......
...@@ -1021,10 +1021,16 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) ...@@ -1021,10 +1021,16 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
&& omp_var_to_track (stmt)) && omp_var_to_track (stmt))
omp_cxx_notice_variable (wtd->omp_ctx, stmt); omp_cxx_notice_variable (wtd->omp_ctx, stmt);
if (is_invisiref_parm (stmt) /* Don't dereference parms in a thunk, pass the references through. */
/* Don't dereference parms in a thunk, pass the references through. */ if ((TREE_CODE (stmt) == CALL_EXPR && CALL_FROM_THUNK_P (stmt))
&& !(DECL_THUNK_P (current_function_decl) || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt)))
&& TREE_CODE (stmt) == PARM_DECL)) {
*walk_subtrees = 0;
return NULL;
}
/* Otherwise, do dereference invisible reference parms. */
if (is_invisiref_parm (stmt))
{ {
*stmt_p = convert_from_reference (stmt); *stmt_p = convert_from_reference (stmt);
*walk_subtrees = 0; *walk_subtrees = 0;
......
...@@ -3409,6 +3409,11 @@ extern void decl_shadowed_for_var_insert (tree, tree); ...@@ -3409,6 +3409,11 @@ extern void decl_shadowed_for_var_insert (tree, tree);
#define AGGR_INIT_ZERO_FIRST(NODE) \ #define AGGR_INIT_ZERO_FIRST(NODE) \
TREE_LANG_FLAG_2 (AGGR_INIT_EXPR_CHECK (NODE)) TREE_LANG_FLAG_2 (AGGR_INIT_EXPR_CHECK (NODE))
/* Nonzero means that the call is the jump from a thunk to the
thunked-to function. */
#define AGGR_INIT_FROM_THUNK_P(NODE) \
(AGGR_INIT_EXPR_CHECK (NODE)->base.protected_flag)
/* AGGR_INIT_EXPR accessors. These are equivalent to the CALL_EXPR /* AGGR_INIT_EXPR accessors. These are equivalent to the CALL_EXPR
accessors, except for AGGR_INIT_EXPR_SLOT (which takes the place of accessors, except for AGGR_INIT_EXPR_SLOT (which takes the place of
CALL_EXPR_STATIC_CHAIN). */ CALL_EXPR_STATIC_CHAIN). */
......
...@@ -4067,6 +4067,7 @@ simplify_aggr_init_expr (tree *tp) ...@@ -4067,6 +4067,7 @@ simplify_aggr_init_expr (tree *tp)
AGGR_INIT_EXPR_ARGP (aggr_init_expr)); AGGR_INIT_EXPR_ARGP (aggr_init_expr));
TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr); TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr);
CALL_EXPR_LIST_INIT_P (call_expr) = CALL_EXPR_LIST_INIT_P (aggr_init_expr); CALL_EXPR_LIST_INIT_P (call_expr) = CALL_EXPR_LIST_INIT_P (aggr_init_expr);
CALL_FROM_THUNK_P (call_expr) = AGGR_INIT_FROM_THUNK_P (aggr_init_expr);
if (style == ctor) if (style == ctor)
{ {
......
...@@ -464,14 +464,22 @@ build_aggr_init_expr (tree type, tree init) ...@@ -464,14 +464,22 @@ build_aggr_init_expr (tree type, tree init)
{ {
slot = build_local_temp (type); slot = build_local_temp (type);
if (TREE_CODE(init) == CALL_EXPR) if (TREE_CODE (init) == CALL_EXPR)
rval = build_aggr_init_array (void_type_node, fn, slot, {
call_expr_nargs (init), rval = build_aggr_init_array (void_type_node, fn, slot,
CALL_EXPR_ARGP (init)); call_expr_nargs (init),
CALL_EXPR_ARGP (init));
AGGR_INIT_FROM_THUNK_P (rval)
= CALL_FROM_THUNK_P (init);
}
else else
rval = build_aggr_init_array (void_type_node, fn, slot, {
aggr_init_expr_nargs (init), rval = build_aggr_init_array (void_type_node, fn, slot,
AGGR_INIT_EXPR_ARGP (init)); aggr_init_expr_nargs (init),
AGGR_INIT_EXPR_ARGP (init));
AGGR_INIT_FROM_THUNK_P (rval)
= AGGR_INIT_FROM_THUNK_P (init);
}
TREE_SIDE_EFFECTS (rval) = 1; TREE_SIDE_EFFECTS (rval) = 1;
AGGR_INIT_VIA_CTOR_P (rval) = is_ctor; AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
TREE_NOTHROW (rval) = TREE_NOTHROW (init); TREE_NOTHROW (rval) = TREE_NOTHROW (init);
......
// PR c++/69889
// { dg-do compile { target c++11 } }
template <typename F> struct Tag {
static void fp() { f()(0); }
static F f() {}
};
struct Dispatch {
template <typename F> Dispatch(F&&) : f(Tag<F>::fp) {}
void (*f)();
};
struct Empty { Empty(Empty&&); };
struct Value {
Value();
template <typename U> Value(U);
void call(Dispatch);
Empty e;
};
struct EmptyValue {
EmptyValue(EmptyValue&&);
EmptyValue();
};
struct User {
User() {
Value().call([](Value) { return EmptyValue(); });
}
};
User user;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment