aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@adacore.com>2019-07-12 13:51:00 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2019-07-12 13:51:00 +0000
commitb847405adee3059762816ab009bc4a5281b5b911 (patch)
tree3ae3db7d3fe556b1cb3773608d0c11f4e9fccf48
parentfdc1f34302906036637445455a53a09f25a4acfd (diff)
downloadgcc-b847405adee3059762816ab009bc4a5281b5b911.zip
gcc-b847405adee3059762816ab009bc4a5281b5b911.tar.gz
gcc-b847405adee3059762816ab009bc4a5281b5b911.tar.bz2
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/gcc.dg/gimplefe-44.c33
-rw-r--r--gcc/tree-eh.c13
4 files changed, 49 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 43b5248..2d1d29f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c235200..debec92 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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>
diff --git a/gcc/testsuite/gcc.dg/gimplefe-44.c b/gcc/testsuite/gcc.dg/gimplefe-44.c
new file mode 100644
index 0000000..a9a92b1
--- /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 fb7d202..5bb07e4 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
{