diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 43b52489921..2d1d29f005c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-07-12 Alexandre Oliva + + * 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 * vector-builder.h (vector_builder::elt): Allow already-supplied diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c2352005a37..debec92a89f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2019-07-12 Alexandre Oliva + * gcc.dg/gimplefe-44.c: New. + * gcc.dg/gimplefe-43.c: New. 2019-07-12 Richard Biener diff --git a/gcc/testsuite/gcc.dg/gimplefe-44.c b/gcc/testsuite/gcc.dg/gimplefe-44.c new file mode 100644 index 00000000000..a9a92b1701e --- /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 fb7d202fc6f..5bb07e49d28 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 {