Commit b847405a by Alexandre Oliva Committed by Alexandre Oliva

allow EH to escape from GIMPLE_EH_ELSE ELSE block

The only preexisting use of GIMPLE_EH_ELSE, for transactional memory
commits, did not allow exceptions to escape from the ELSE path.  The
trick it uses to allow the ELSE path to see the propagating exception
does not work very well if the exception cleanup raises further
exceptions: the ELSE block is configured to handle exceptions in
itself.  This confuses the heck out of CFG and EH cleanups.

Basing the lowering context for the ELSE block on outer_state, rather
than this_state, gets us the expected enclosing handler.


for  gcc/ChangeLog

	* tree-eh.c (honor_protect_cleanup_actions): Use outer_
	rather than this_state as the lowering context for the ELSE
	seq in a GIMPLE_EH_ELSE.

for  gcc/testsuite/ChangeLog

	* gcc.dg/gimplefe-44.c: New.

From-SVN: r273444
parent fdc1f343
2019-07-12 Alexandre Oliva <oliva@adacore.com>
* tree-eh.c (honor_protect_cleanup_actions): Use outer_
rather than this_state as the lowering context for the ELSE
seq in a GIMPLE_EH_ELSE.
2019-07-12 Richard Sandiford <richard.sandiford@arm.com>
* vector-builder.h (vector_builder::elt): Allow already-supplied
......
2019-07-12 Alexandre Oliva <oliva@adacore.com>
* gcc.dg/gimplefe-44.c: New.
* gcc.dg/gimplefe-43.c: New.
2019-07-12 Richard Biener <rguenther@suse.de>
......
/* { dg-do compile } */
/* { dg-options "-fexceptions -fgimple -fdump-tree-eh-eh" } */
void __GIMPLE foo()
{
try
{
try
{
extern void might_throw1 ();
might_throw1 ();
}
finally
{
extern void might_throw2 ();
might_throw2 ();
}
else
{
extern void might_throw3 ();
might_throw3 ();
}
}
finally
{
extern void might_throw4 ();
might_throw4 ();
}
}
/* { dg-final { scan-tree-dump ".LP 1. might_throw1" "eh" } } */
/* { dg-final { scan-tree-dump ".LP 2. might_throw2" "eh" } } */
/* { dg-final { scan-tree-dump ".LP 2. might_throw3" "eh" } } */
......@@ -996,11 +996,14 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
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;
/* Let the ELSE see the exception that's being processed, but
since the cleanup is outside the try block, process it with
outer_state, otherwise it may be used as a cleanup for
itself, and Bad Things (TM) ensue. */
eh_region save_ehp = outer_state->ehp_region;
outer_state->ehp_region = this_state->cur_region;
lower_eh_constructs_1 (outer_state, &finally);
outer_state->ehp_region = save_ehp;
}
else
{
......
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