diff options
author | Jan Hubicka <jh@suse.cz> | 2005-05-28 00:50:41 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2005-05-27 22:50:41 +0000 |
commit | b59fa6cf91b357b25e00dd3f1c3e88dd5d0220e2 (patch) | |
tree | 9b52f4570bb28084ba650786b833a780a6ea3ad1 /gcc | |
parent | ea497bb84cf1e43948fd78d1d4a985182a91c0cd (diff) | |
download | gcc-b59fa6cf91b357b25e00dd3f1c3e88dd5d0220e2.zip gcc-b59fa6cf91b357b25e00dd3f1c3e88dd5d0220e2.tar.gz gcc-b59fa6cf91b357b25e00dd3f1c3e88dd5d0220e2.tar.bz2 |
except.c (can_throw_internal_1, [...]): Add "is_resx" argument.
* except.c (can_throw_internal_1, can_throw_external_1): Add
"is_resx" argument.
(can_throw_external, can_throw_internal): Bring into sync wrt
dealing resx.
* except.h (can_throw_internal_1, can_throw_external_1): Update
prototype.
* tree-eh.c (tree_can_throw_internal, tree_can_throw_external):
Deal properly with resx.
From-SVN: r100282
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/except.c | 23 | ||||
-rw-r--r-- | gcc/except.h | 4 | ||||
-rw-r--r-- | gcc/tree-eh.c | 10 |
4 files changed, 35 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b46c46d..49537c9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2005-05-28 Jan Hubicka <jh@suse.cz> + + * except.c (can_throw_internal_1, can_throw_external_1): Add + "is_resx" argument. + (can_throw_external, can_throw_internal): Bring into sync wrt + dealing resx. + * except.h (can_throw_internal_1, can_throw_external_1): Update + prototype. + * tree-eh.c (tree_can_throw_internal, tree_can_throw_external): + Deal properly with resx. + 2005-05-27 Kazu Hirata <kazu@cs.umass.edu> * basic-block.h (basic_block_def): Add phi_nodes and diff --git a/gcc/except.c b/gcc/except.c index 9f1bfe9..7859412 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -2539,7 +2539,7 @@ reachable_handlers (rtx insn) within the function. */ bool -can_throw_internal_1 (int region_number) +can_throw_internal_1 (int region_number, bool is_resx) { struct eh_region *region; tree type_thrown; @@ -2547,7 +2547,9 @@ can_throw_internal_1 (int region_number) region = cfun->eh->region_array[region_number]; type_thrown = NULL_TREE; - if (region->type == ERT_THROW) + if (is_resx) + region = region->outer; + else if (region->type == ERT_THROW) { type_thrown = region->u.throw.type; region = region->outer; @@ -2579,7 +2581,7 @@ can_throw_internal (rtx insn) if (JUMP_P (insn) && GET_CODE (PATTERN (insn)) == RESX && XINT (PATTERN (insn), 0) > 0) - return can_throw_internal_1 (XINT (PATTERN (insn), 0)); + return can_throw_internal_1 (XINT (PATTERN (insn), 0), true); if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE) @@ -2590,14 +2592,14 @@ can_throw_internal (rtx insn) if (!note || INTVAL (XEXP (note, 0)) <= 0) return false; - return can_throw_internal_1 (INTVAL (XEXP (note, 0))); + return can_throw_internal_1 (INTVAL (XEXP (note, 0)), false); } /* Determine if the given INSN can throw an exception that is visible outside the function. */ bool -can_throw_external_1 (int region_number) +can_throw_external_1 (int region_number, bool is_resx) { struct eh_region *region; tree type_thrown; @@ -2605,7 +2607,9 @@ can_throw_external_1 (int region_number) region = cfun->eh->region_array[region_number]; type_thrown = NULL_TREE; - if (region->type == ERT_THROW) + if (is_resx) + region = region->outer; + else if (region->type == ERT_THROW) { type_thrown = region->u.throw.type; region = region->outer; @@ -2628,6 +2632,11 @@ can_throw_external (rtx insn) if (! INSN_P (insn)) return false; + if (JUMP_P (insn) + && GET_CODE (PATTERN (insn)) == RESX + && XINT (PATTERN (insn), 0) > 0) + return can_throw_external_1 (XINT (PATTERN (insn), 0), true); + if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE) insn = XVECEXP (PATTERN (insn), 0, 0); @@ -2647,7 +2656,7 @@ can_throw_external (rtx insn) if (INTVAL (XEXP (note, 0)) <= 0) return false; - return can_throw_external_1 (INTVAL (XEXP (note, 0))); + return can_throw_external_1 (INTVAL (XEXP (note, 0)), false); } /* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */ diff --git a/gcc/except.h b/gcc/except.h index 9526b86..9188c3bb 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -46,9 +46,9 @@ extern void for_each_eh_label (void (*) (rtx)); extern void for_each_eh_region (void (*) (struct eh_region *)); /* Determine if the given INSN can throw an exception. */ -extern bool can_throw_internal_1 (int); +extern bool can_throw_internal_1 (int, bool); extern bool can_throw_internal (rtx); -extern bool can_throw_external_1 (int); +extern bool can_throw_external_1 (int, bool); extern bool can_throw_external (rtx); /* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */ diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 9f641e1..294e309 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2009,29 +2009,31 @@ bool tree_can_throw_internal (tree stmt) { int region_nr; + bool is_resx = false; if (TREE_CODE (stmt) == RESX_EXPR) - region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)); + region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)), is_resx = true; else region_nr = lookup_stmt_eh_region (stmt); if (region_nr < 0) return false; - return can_throw_internal_1 (region_nr); + return can_throw_internal_1 (region_nr, is_resx); } bool tree_can_throw_external (tree stmt) { int region_nr; + bool is_resx = false; if (TREE_CODE (stmt) == RESX_EXPR) - region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)); + region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)), is_resx = true; else region_nr = lookup_stmt_eh_region (stmt); if (region_nr < 0) return tree_could_throw_p (stmt); else - return can_throw_external_1 (region_nr); + return can_throw_external_1 (region_nr, is_resx); } /* Given a statement OLD_STMT and a new statement NEW_STMT that has replaced |