aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>2000-03-08 16:30:17 -0500
committerJason Merrill <jason@gcc.gnu.org>2000-03-08 16:30:17 -0500
commit6814a8a0bbfca8cd39b2e68ab74a1f3bd2e19c5a (patch)
tree5ebf91de1a0adafc35062b23a2450bd867d352f7 /gcc
parent2b01d2d999a4fa1e0ce9b7b9d85ebaedfc726043 (diff)
downloadgcc-6814a8a0bbfca8cd39b2e68ab74a1f3bd2e19c5a.zip
gcc-6814a8a0bbfca8cd39b2e68ab74a1f3bd2e19c5a.tar.gz
gcc-6814a8a0bbfca8cd39b2e68ab74a1f3bd2e19c5a.tar.bz2
flow.c (count_basic_blocks, [...]): A rethrow can occur outside of an EH region.
* flow.c (count_basic_blocks, find_basic_blocks_1): A rethrow can occur outside of an EH region. * except.c: Correct comments about rethrow behavior. (rethrow_symbol_map): Do nothing if !flag_new_exceptions. * flow.c (make_edges): Always call make_eh_edge for calls. From-SVN: r32432
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/except.c52
-rw-r--r--gcc/flow.c20
3 files changed, 54 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index be50eae..17ab03e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2000-03-08 Jason Merrill <jason@casey.cygnus.com>
+
+ * flow.c (count_basic_blocks, find_basic_blocks_1): A rethrow
+ can occur outside of an EH region.
+ * except.c: Correct comments about rethrow behavior.
+ (rethrow_symbol_map): Do nothing if !flag_new_exceptions.
+
+2000-03-08 Andrew MacLeod <amacleod@cygnus.com>
+
+ * flow.c (make_edges): Always call make_eh_edge for calls.
+
2000-03-08 Zack Weinberg <zack@wolery.cumb.org>
* cpplib.h (parse_underflow_t, CPP_NULL_BUFFER): Delete.
diff --git a/gcc/except.c b/gcc/except.c
index 405a53f..7ecfaf8 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -495,6 +495,7 @@ static int eh_region_from_symbol PARAMS ((rtx));
extern struct obstack permanent_obstack;
/* Generate a SYMBOL_REF for rethrow to use */
+
static rtx
create_rethrow_ref (region_num)
int region_num;
@@ -566,7 +567,7 @@ top_label_entry (stack)
return (*stack)->u.tlabel;
}
-/* get an exception label. These must be on the permanent obstack */
+/* Get an exception label. */
rtx
gen_exception_label ()
@@ -602,7 +603,8 @@ push_eh_entry (stack)
stack->top = node;
}
-/* push an existing entry onto a stack. */
+/* Push an existing entry onto a stack. */
+
static void
push_entry (stack, entry)
struct eh_stack *stack;
@@ -695,7 +697,7 @@ struct func_eh_entry
{
int range_number; /* EH region number from EH NOTE insn's. */
rtx rethrow_label; /* Label for rethrow. */
- int rethrow_ref; /* Is rethrow referenced? */
+ int rethrow_ref; /* Is rethrow_label referenced? */
struct handler_info *handlers;
};
@@ -969,6 +971,7 @@ duplicate_eh_handlers (old_note_eh_region, new_note_eh_region, map)
/* Given a rethrow symbol, find the EH region number this is for. */
+
static int
eh_region_from_symbol (sym)
rtx sym;
@@ -984,6 +987,7 @@ eh_region_from_symbol (sym)
/* Like find_func_region, but using the rethrow symbol for the region
rather than the region number itself. */
+
static int
find_func_region_from_symbol (sym)
rtx sym;
@@ -995,12 +999,17 @@ find_func_region_from_symbol (sym)
__rethrow as well. This performs the remap. If a symbol isn't foiund,
the original one is returned. This is not an efficient routine,
so don't call it on everything!! */
+
rtx
rethrow_symbol_map (sym, map)
rtx sym;
rtx (*map) PARAMS ((rtx));
{
int x, y;
+
+ if (! flag_new_exceptions)
+ return sym;
+
for (x = 0; x < current_func_eh_entry; x++)
if (function_eh_regions[x].rethrow_label == sym)
{
@@ -1021,6 +1030,10 @@ rethrow_symbol_map (sym, map)
return sym;
}
+/* Returns nonzero if the rethrow label for REGION is referenced
+ somewhere (i.e. we rethrow out of REGION or some other region
+ masquerading as REGION). */
+
int
rethrow_used (region)
int region;
@@ -2011,7 +2024,7 @@ expand_rethrow (label)
label = last_rethrow_symbol;
emit_library_call (rethrow_libfunc, 0, VOIDmode, 1, label, Pmode);
region = find_func_region (eh_region_from_symbol (label));
- /* If the region is -1, it doesn't exist yet. We should be
+ /* If the region is -1, it doesn't exist yet. We shouldn't be
trying to rethrow there yet. */
if (region == -1)
abort ();
@@ -2194,14 +2207,12 @@ output_exception_table_entry (file, n)
int index = find_func_region (n);
rtx rethrow;
- /* form and emit the rethrow label, if needed */
- rethrow = function_eh_regions[index].rethrow_label;
- if (rethrow != NULL_RTX && !flag_new_exceptions)
- rethrow = NULL_RTX;
- if (rethrow != NULL_RTX && handler == NULL)
- if (! function_eh_regions[index].rethrow_ref)
- rethrow = NULL_RTX;
-
+ /* Form and emit the rethrow label, if needed */
+ if (flag_new_exceptions
+ && (handler || function_eh_regions[index].rethrow_ref))
+ rethrow = function_eh_regions[index].rethrow_label;
+ else
+ rethrow = NULL_RTX;
for ( ; handler != NULL || rethrow != NULL_RTX; handler = handler->next)
{
@@ -2301,7 +2312,7 @@ output_exception_table ()
if (i != 0)
assemble_integer (const0_rtx, i , 1);
- /* Generate the label for offset calculations on rethrows */
+ /* Generate the label for offset calculations on rethrows. */
ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", 0);
assemble_label(buf);
}
@@ -2318,7 +2329,7 @@ output_exception_table ()
assemble_label(buf);
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
- /* for binary compatability, the old __throw checked the second
+ /* For binary compatibility, the old __throw checked the second
position for a -1, so we should output at least 2 -1's */
if (! flag_new_exceptions)
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
@@ -2666,7 +2677,7 @@ scan_region (insn, n, delete_outer)
/* Assume we can delete the region. */
int delete = 1;
- /* Can't delete something which is rethrown to. */
+ /* Can't delete something which is rethrown from. */
if (rethrow_used (n))
delete = 0;
@@ -2783,9 +2794,10 @@ exception_optimize ()
}
}
-/* This function determines whether any of the exception regions in the
- current function are targets of a rethrow or not, and set the
- reference flag according. */
+/* This function determines whether the rethrow labels for any of the
+ exception regions in the current function are used or not, and set
+ the reference flag according. */
+
void
update_rethrow_references ()
{
@@ -2800,7 +2812,7 @@ update_rethrow_references ()
saw_rethrow = (int *) xcalloc (current_func_eh_entry, sizeof (int));
/* Determine what regions exist, and whether there are any rethrows
- to those regions or not. */
+ from those regions or not. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == CALL_INSN)
{
@@ -3336,7 +3348,7 @@ reachable_handlers (block, info, insn, handlers)
if (insn && GET_CODE (insn) == CALL_INSN)
{
/* RETHROWs specify a region number from which we are going to rethrow.
- This means we wont pass control to handlers in the specified
+ This means we won't pass control to handlers in the specified
region, but rather any region OUTSIDE the specified region.
We accomplish this by setting block to the outer_index of the
specified region. */
diff --git a/gcc/flow.c b/gcc/flow.c
index e134794..5704835 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -469,8 +469,9 @@ count_basic_blocks (f)
prev_call = insn;
call_had_abnormal_edge = 0;
- /* If there is a specified EH region, we have an edge. */
- if (eh_region && region > 0)
+ /* If there is an EH region or rethrow, we have an edge. */
+ if ((eh_region && region > 0)
+ || find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
call_had_abnormal_edge = 1;
else
{
@@ -541,8 +542,9 @@ find_basic_blocks_1 (f)
int region = (note ? XWINT (XEXP (note, 0), 0) : 1);
call_has_abnormal_edge = 0;
- /* If there is an EH region, we have an edge. */
- if (eh_list && region > 0)
+ /* If there is an EH region or rethrow, we have an edge. */
+ if ((eh_list && region > 0)
+ || find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
call_has_abnormal_edge = 1;
else
{
@@ -983,10 +985,10 @@ make_edges (label_value_list)
if (code == CALL_INSN || asynchronous_exceptions)
{
- /* If there's an EH region active at the end of a block,
- add the appropriate edges. */
- if (bb->eh_end >= 0)
- make_eh_edge (edge_cache, eh_nest_info, bb, insn, bb->eh_end);
+ /* Add any appropriate EH edges. We do this unconditionally
+ since there may be a REG_EH_REGION or REG_EH_RETHROW note
+ on the call, and this needn't be within an EH region. */
+ make_eh_edge (edge_cache, eh_nest_info, bb, insn, bb->eh_end);
/* If we have asynchronous exceptions, do the same for *all*
exception regions active in the block. */
@@ -1778,7 +1780,7 @@ delete_eh_regions ()
{
int num = NOTE_EH_HANDLER (insn);
/* A NULL handler indicates a region is no longer needed,
- as long as it isn't the target of a rethrow. */
+ as long as its rethrow label isn't used. */
if (get_first_handler (num) == NULL && ! rethrow_used (num))
{
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;