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
This commit is contained in:
Alexandre Oliva 2019-07-12 13:51:00 +00:00 committed by Alexandre Oliva
parent fdc1f34302
commit b847405ade
4 changed files with 49 additions and 5 deletions

View file

@ -1,3 +1,9 @@
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

View file

@ -1,5 +1,7 @@
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>

View file

@ -0,0 +1,33 @@
/* { 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" } } */

View file

@ -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
{