From: Jason Merrill Date: Wed, 8 Mar 2000 21:30:17 +0000 (-0500) Subject: flow.c (count_basic_blocks, [...]): A rethrow can occur outside of an EH region. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6814a8a0bbfca8cd39b2e68ab74a1f3bd2e19c5a;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index be50eae8691..17ab03e7a19 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2000-03-08 Jason Merrill + + * 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 + + * flow.c (make_edges): Always call make_eh_edge for calls. + 2000-03-08 Zack Weinberg * cpplib.h (parse_underflow_t, CPP_NULL_BUFFER): Delete. diff --git a/gcc/except.c b/gcc/except.c index 405a53f24cb..7ecfaf85c21 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 e134794f38c..570483567a3 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;