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
This commit is contained in:
parent
2b01d2d999
commit
6814a8a0bb
3 changed files with 54 additions and 29 deletions
|
@ -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.
|
||||
|
|
52
gcc/except.c
52
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. */
|
||||
|
|
20
gcc/flow.c
20
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue