On Thu, Jul 11, 2019 at 12:44 PM Alexandre Oliva <ol...@adacore.com> wrote: > > ... and here's a patch that uses a try/finally/else gimplefe test to > demonstrate the GIMPLE_EH_ELSE lowering problem (might_throw3 is tagged > as [LP 1] rather than [LP 2]), and fixes it. > > Regstrapped on x86_64-linux-gnu. Ok to install?
OK. Richard. > > 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. > --- > gcc/testsuite/gcc.dg/gimplefe-44.c | 33 +++++++++++++++++++++++++++++++++ > gcc/tree-eh.c | 13 ++++++++----- > 2 files changed, 41 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/gimplefe-44.c > > diff --git a/gcc/testsuite/gcc.dg/gimplefe-44.c > b/gcc/testsuite/gcc.dg/gimplefe-44.c > new file mode 100644 > index 000000000000..a9a92b1701ec > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/gimplefe-44.c > @@ -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" } } */ > diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c > index fb7d202fc6f9..5bb07e49d285 100644 > --- a/gcc/tree-eh.c > +++ b/gcc/tree-eh.c > @@ -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 > { > > > -- > Alexandre Oliva, freedom fighter he/him https://FSFLA.org/blogs/lxo > Be the change, be Free! FSF Latin America board member > GNU Toolchain Engineer Free Software Evangelist > Hay que enGNUrecerse, pero sin perder la terGNUra jamás - Che GNUevara