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:
parent
7c11b0fef0
commit
b5c4bc31ba
|
@ -33,6 +33,9 @@
|
||||||
(ipa_tm_scan_calls_transaction): ... not here.
|
(ipa_tm_scan_calls_transaction): ... not here.
|
||||||
(ipa_uninstrument_transaction): Remove.
|
(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>
|
2015-12-22 Peter Bergner <bergner@vnet.ibm.com>
|
||||||
|
|
||||||
PR target/68772
|
PR target/68772
|
||||||
|
|
|
@ -986,36 +986,35 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
|
||||||
struct leh_state *this_state,
|
struct leh_state *this_state,
|
||||||
struct leh_tf_state *tf)
|
struct leh_tf_state *tf)
|
||||||
{
|
{
|
||||||
tree protect_cleanup_actions;
|
gimple_seq finally = gimple_try_cleanup (tf->top_p);
|
||||||
gimple_stmt_iterator gsi;
|
|
||||||
bool finally_may_fallthru;
|
|
||||||
gimple_seq finally;
|
|
||||||
gimple *x;
|
|
||||||
geh_mnt *eh_mnt;
|
|
||||||
gtry *try_stmt;
|
|
||||||
geh_else *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))
|
||||||
|
{
|
||||||
|
gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else));
|
||||||
|
finally = gimple_eh_else_e_body (eh_else);
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
{
|
||||||
/* First check for nothing to do. */
|
/* First check for nothing to do. */
|
||||||
if (lang_hooks.eh_protect_cleanup_actions == NULL)
|
if (lang_hooks.eh_protect_cleanup_actions == NULL)
|
||||||
return;
|
return;
|
||||||
protect_cleanup_actions = lang_hooks.eh_protect_cleanup_actions ();
|
tree actions = lang_hooks.eh_protect_cleanup_actions ();
|
||||||
if (protect_cleanup_actions == NULL)
|
if (actions == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
finally = gimple_try_cleanup (tf->top_p);
|
if (this_state)
|
||||||
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)
|
|
||||||
{
|
|
||||||
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,
|
finally = lower_try_finally_dup_block (finally, outer_state,
|
||||||
gimple_location (tf->try_finally_expr));
|
gimple_location (tf->try_finally_expr));
|
||||||
finally_may_fallthru = gimple_seq_may_fallthru (finally);
|
|
||||||
|
|
||||||
/* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
|
/* 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
|
set, the handler of the TRY_CATCH_EXPR is another cleanup which ought
|
||||||
|
@ -1024,8 +1023,8 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
|
||||||
cp/decl.c). Since it's logically at an outer level, we should call
|
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
|
terminate before we get to it, so strip it away before adding the
|
||||||
MUST_NOT_THROW filter. */
|
MUST_NOT_THROW filter. */
|
||||||
gsi = gsi_start (finally);
|
gimple_stmt_iterator gsi = gsi_start (finally);
|
||||||
x = gsi_stmt (gsi);
|
gimple *x = gsi_stmt (gsi);
|
||||||
if (gimple_code (x) == GIMPLE_TRY
|
if (gimple_code (x) == GIMPLE_TRY
|
||||||
&& gimple_try_kind (x) == GIMPLE_TRY_CATCH
|
&& gimple_try_kind (x) == GIMPLE_TRY_CATCH
|
||||||
&& gimple_try_catch_is_cleanup (x))
|
&& gimple_try_catch_is_cleanup (x))
|
||||||
|
@ -1035,15 +1034,17 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrap the block with protect_cleanup_actions as the action. */
|
/* Wrap the block with protect_cleanup_actions as the action. */
|
||||||
eh_mnt = gimple_build_eh_must_not_throw (protect_cleanup_actions);
|
geh_mnt *eh_mnt = gimple_build_eh_must_not_throw (actions);
|
||||||
try_stmt = gimple_build_try (finally, gimple_seq_alloc_with_stmt (eh_mnt),
|
gtry *try_stmt = gimple_build_try (finally,
|
||||||
|
gimple_seq_alloc_with_stmt (eh_mnt),
|
||||||
GIMPLE_TRY_CATCH);
|
GIMPLE_TRY_CATCH);
|
||||||
finally = lower_eh_must_not_throw (outer_state, try_stmt);
|
finally = lower_eh_must_not_throw (outer_state, try_stmt);
|
||||||
|
}
|
||||||
|
|
||||||
/* Drop all of this into the exception sequence. */
|
/* Drop all of this into the exception sequence. */
|
||||||
emit_post_landing_pad (&eh_seq, tf->region);
|
emit_post_landing_pad (&eh_seq, tf->region);
|
||||||
gimple_seq_add_seq (&eh_seq, finally);
|
gimple_seq_add_seq (&eh_seq, finally);
|
||||||
if (finally_may_fallthru)
|
if (gimple_seq_may_fallthru (finally))
|
||||||
emit_resx (&eh_seq, tf->region);
|
emit_resx (&eh_seq, tf->region);
|
||||||
|
|
||||||
/* Having now been handled, EH isn't to be considered with
|
/* Having now been handled, EH isn't to be considered with
|
||||||
|
|
Loading…
Reference in New Issue