Give EH_ELSE access to __builtin_eh_pointer

The must-not-throw wrapper for protect_cleanup_actions gets in
the way of being able to access __builtin_eh_pointer without
confusion as the identit of the exception to which we are
referring (b_eh_p has no usable argument up to this point).

Since EH_ELSE never comes from user derived code, let's drop
the c++ specific wrapping.

	* tree-eh.c (honor_protect_cleanup_actions): Do not wrap
	eh_else in a must-not-throw; set ehp_region for it too.

From-SVN: r231908
This commit is contained in:
Richard Henderson 2015-12-22 11:42:31 -08:00 committed by Richard Henderson
parent 7c11b0fef0
commit b5c4bc31ba
2 changed files with 52 additions and 48 deletions

View File

@ -33,6 +33,9 @@
(ipa_tm_scan_calls_transaction): ... not here.
(ipa_uninstrument_transaction): Remove.
* tree-eh.c (honor_protect_cleanup_actions): Do not wrap eh_else
in a must-not-throw; set ehp_region for it too.
2015-12-22 Peter Bergner <bergner@vnet.ibm.com>
PR target/68772

View File

@ -986,64 +986,65 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
struct leh_state *this_state,
struct leh_tf_state *tf)
{
tree protect_cleanup_actions;
gimple_stmt_iterator gsi;
bool finally_may_fallthru;
gimple_seq finally;
gimple *x;
geh_mnt *eh_mnt;
gtry *try_stmt;
geh_else *eh_else;
gimple_seq finally = gimple_try_cleanup (tf->top_p);
/* First check for nothing to do. */
if (lang_hooks.eh_protect_cleanup_actions == NULL)
return;
protect_cleanup_actions = lang_hooks.eh_protect_cleanup_actions ();
if (protect_cleanup_actions == NULL)
return;
finally = gimple_try_cleanup (tf->top_p);
eh_else = get_eh_else (finally);
/* Duplicate the FINALLY block. Only need to do this for try-finally,
and not for cleanups. If we've got an EH_ELSE, extract it now. */
if (eh_else)
/* EH_ELSE doesn't come from user code; only compiler generated stuff.
It does need to be handled here, so as to separate the (different)
EH path from the normal path. But we should not attempt to wrap
it with a must-not-throw node (which indeed gets in the way). */
if (geh_else *eh_else = get_eh_else (finally))
{
finally = gimple_eh_else_e_body (eh_else);
gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else));
}
else if (this_state)
finally = lower_try_finally_dup_block (finally, outer_state,
gimple_location (tf->try_finally_expr));
finally_may_fallthru = gimple_seq_may_fallthru (finally);
finally = gimple_eh_else_e_body (eh_else);
/* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
set, the handler of the TRY_CATCH_EXPR is another cleanup which ought
to be in an enclosing scope, but needs to be implemented at this level
to avoid a nesting violation (see wrap_temporary_cleanups in
cp/decl.c). Since it's logically at an outer level, we should call
terminate before we get to it, so strip it away before adding the
MUST_NOT_THROW filter. */
gsi = gsi_start (finally);
x = gsi_stmt (gsi);
if (gimple_code (x) == GIMPLE_TRY
&& gimple_try_kind (x) == GIMPLE_TRY_CATCH
&& gimple_try_catch_is_cleanup (x))
/* Let the ELSE see the exception that's being processed. */
eh_region save_ehp = this_state->ehp_region;
this_state->ehp_region = this_state->cur_region;
lower_eh_constructs_1 (this_state, &finally);
this_state->ehp_region = save_ehp;
}
else
{
gsi_insert_seq_before (&gsi, gimple_try_eval (x), GSI_SAME_STMT);
gsi_remove (&gsi, false);
}
/* First check for nothing to do. */
if (lang_hooks.eh_protect_cleanup_actions == NULL)
return;
tree actions = lang_hooks.eh_protect_cleanup_actions ();
if (actions == NULL)
return;
/* Wrap the block with protect_cleanup_actions as the action. */
eh_mnt = gimple_build_eh_must_not_throw (protect_cleanup_actions);
try_stmt = gimple_build_try (finally, gimple_seq_alloc_with_stmt (eh_mnt),
GIMPLE_TRY_CATCH);
finally = lower_eh_must_not_throw (outer_state, try_stmt);
if (this_state)
finally = lower_try_finally_dup_block (finally, outer_state,
gimple_location (tf->try_finally_expr));
/* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
set, the handler of the TRY_CATCH_EXPR is another cleanup which ought
to be in an enclosing scope, but needs to be implemented at this level
to avoid a nesting violation (see wrap_temporary_cleanups in
cp/decl.c). Since it's logically at an outer level, we should call
terminate before we get to it, so strip it away before adding the
MUST_NOT_THROW filter. */
gimple_stmt_iterator gsi = gsi_start (finally);
gimple *x = gsi_stmt (gsi);
if (gimple_code (x) == GIMPLE_TRY
&& gimple_try_kind (x) == GIMPLE_TRY_CATCH
&& gimple_try_catch_is_cleanup (x))
{
gsi_insert_seq_before (&gsi, gimple_try_eval (x), GSI_SAME_STMT);
gsi_remove (&gsi, false);
}
/* Wrap the block with protect_cleanup_actions as the action. */
geh_mnt *eh_mnt = gimple_build_eh_must_not_throw (actions);
gtry *try_stmt = gimple_build_try (finally,
gimple_seq_alloc_with_stmt (eh_mnt),
GIMPLE_TRY_CATCH);
finally = lower_eh_must_not_throw (outer_state, try_stmt);
}
/* Drop all of this into the exception sequence. */
emit_post_landing_pad (&eh_seq, tf->region);
gimple_seq_add_seq (&eh_seq, finally);
if (finally_may_fallthru)
if (gimple_seq_may_fallthru (finally))
emit_resx (&eh_seq, tf->region);
/* Having now been handled, EH isn't to be considered with