X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fexcept.c;h=c67a98205a251a12d33a89005393ecd04ea5c2c3;hb=d409f4c999310fd5a896e24614f7e114241d8171;hp=21ade90cb60d46ddd681086e1b0be6911f3c4f91;hpb=e24e8df7f2b15e0e0378aa8b65d85f1d3b8a348e;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/except.c b/gcc/except.c index 21ade90cb60..c67a98205a2 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -260,8 +260,6 @@ static hashval_t t2r_hash (const void *); static void add_type_for_runtime (tree); static tree lookup_type_for_runtime (tree); -static struct eh_region *expand_eh_region_end (void); - static void resolve_fixup_regions (void); static void remove_fixup_regions (void); static void remove_unreachable_regions (rtx); @@ -378,7 +376,7 @@ init_eh (void) integer_type_node); DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node; - tmp = build_index_type (build_int_2 (4 - 1, 0)); + tmp = build_index_type (build_int_cst (NULL_TREE, 4 - 1)); tmp = build_array_type (lang_hooks.types.type_for_mode (word_mode, 1), tmp); f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp); @@ -394,17 +392,17 @@ init_eh (void) #ifdef DONT_USE_BUILTIN_SETJMP #ifdef JMP_BUF_SIZE - tmp = build_int_2 (JMP_BUF_SIZE - 1, 0); + tmp = build_int_cst (NULL_TREE, JMP_BUF_SIZE - 1); #else /* Should be large enough for most systems, if it is not, JMP_BUF_SIZE should be defined with the proper value. It will also tend to be larger than necessary for most systems, a more optimal port will define JMP_BUF_SIZE. */ - tmp = build_int_2 (FIRST_PSEUDO_REGISTER + 2 - 1, 0); + tmp = build_int_cst (NULL_TREE, FIRST_PSEUDO_REGISTER + 2 - 1); #endif #else /* builtin_setjmp takes a pointer to 5 words. */ - tmp = build_int_2 (5 * BITS_PER_WORD / POINTER_SIZE - 1, 0); + tmp = build_int_cst (NULL_TREE, 5 * BITS_PER_WORD / POINTER_SIZE - 1); #endif tmp = build_index_type (tmp); tmp = build_array_type (ptr_type_node, tmp); @@ -462,8 +460,7 @@ gen_eh_region (enum eh_region_type type, struct eh_region *outer) struct eh_region *new; #ifdef ENABLE_CHECKING - if (! doing_eh (0)) - abort (); + gcc_assert (doing_eh (0)); #endif /* Insert a new blank region as a leaf in the tree. */ @@ -574,141 +571,6 @@ set_eh_region_tree_label (struct eh_region *region, tree lab) region->tree_label = lab; } -/* Start an exception handling region. All instructions emitted - after this point are considered to be part of the region until - expand_eh_region_end is invoked. */ - -void -expand_eh_region_start (void) -{ - struct eh_region *new; - rtx note; - - if (! doing_eh (0)) - return; - - new = gen_eh_region (ERT_UNKNOWN, cfun->eh->cur_region); - cfun->eh->cur_region = new; - - /* Create a note marking the start of this region. */ - note = emit_note (NOTE_INSN_EH_REGION_BEG); - NOTE_EH_HANDLER (note) = new->region_number; -} - -/* Common code to end a region. Returns the region just ended. */ - -static struct eh_region * -expand_eh_region_end (void) -{ - struct eh_region *cur_region = cfun->eh->cur_region; - rtx note; - - /* Create a note marking the end of this region. */ - note = emit_note (NOTE_INSN_EH_REGION_END); - NOTE_EH_HANDLER (note) = cur_region->region_number; - - /* Pop. */ - cfun->eh->cur_region = cur_region->outer; - - return cur_region; -} - -/* Expand HANDLER, which is the operand 1 of a TRY_CATCH_EXPR. Catch - blocks and C++ exception-specifications are handled specially. */ - -void -expand_eh_handler (tree handler) -{ - tree inner = expr_first (handler); - - switch (TREE_CODE (inner)) - { - case CATCH_EXPR: - expand_start_all_catch (); - expand_expr (handler, const0_rtx, VOIDmode, 0); - expand_end_all_catch (); - break; - - case EH_FILTER_EXPR: - if (EH_FILTER_MUST_NOT_THROW (handler)) - expand_eh_region_end_must_not_throw (EH_FILTER_FAILURE (handler)); - else - expand_eh_region_end_allowed (EH_FILTER_TYPES (handler), - EH_FILTER_FAILURE (handler)); - break; - - default: - expand_eh_region_end_cleanup (handler); - break; - } -} - -/* End an exception handling region for a cleanup. HANDLER is an - expression to expand for the cleanup. */ - -void -expand_eh_region_end_cleanup (tree handler) -{ - struct eh_region *region; - tree protect_cleanup_actions; - rtx around_label; - rtx data_save[2]; - - if (! doing_eh (0)) - return; - - region = expand_eh_region_end (); - region->type = ERT_CLEANUP; - region->label = gen_label_rtx (); - region->u.cleanup.exp = handler; - region->u.cleanup.prev_try = cfun->eh->try_region; - - around_label = gen_label_rtx (); - emit_jump (around_label); - - emit_label (region->label); - - if (flag_non_call_exceptions || region->may_contain_throw) - { - /* Give the language a chance to specify an action to be taken if an - exception is thrown that would propagate out of the HANDLER. */ - protect_cleanup_actions - = (lang_protect_cleanup_actions - ? (*lang_protect_cleanup_actions) () - : NULL_TREE); - - if (protect_cleanup_actions) - expand_eh_region_start (); - - /* In case this cleanup involves an inline destructor with a try block in - it, we need to save the EH return data registers around it. */ - data_save[0] = gen_reg_rtx (ptr_mode); - emit_move_insn (data_save[0], get_exception_pointer (cfun)); - data_save[1] = gen_reg_rtx (word_mode); - emit_move_insn (data_save[1], get_exception_filter (cfun)); - - expand_expr (handler, const0_rtx, VOIDmode, 0); - - emit_move_insn (cfun->eh->exc_ptr, data_save[0]); - emit_move_insn (cfun->eh->filter, data_save[1]); - - if (protect_cleanup_actions) - expand_eh_region_end_must_not_throw (protect_cleanup_actions); - - /* We need any stack adjustment complete before the around_label. */ - do_pending_stack_adjust (); - } - - /* We delay the generation of the _Unwind_Resume until we generate - landing pads. We emit a marker here so as to get good control - flow data in the meantime. */ - region->resume - = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number)); - emit_barrier (); - - emit_label (around_label); -} - void expand_resx_expr (tree exp) { @@ -719,197 +581,6 @@ expand_resx_expr (tree exp) emit_barrier (); } -/* End an exception handling region for a try block, and prepares - for subsequent calls to expand_start_catch. */ - -void -expand_start_all_catch (void) -{ - struct eh_region *region; - - if (! doing_eh (1)) - return; - - region = expand_eh_region_end (); - region->type = ERT_TRY; - region->u.try.prev_try = cfun->eh->try_region; - region->u.try.continue_label = gen_label_rtx (); - - cfun->eh->try_region = region; - - emit_jump (region->u.try.continue_label); -} - -/* Begin a catch clause. TYPE is the type caught, a list of such - types, (in the case of Java) an ADDR_EXPR which points to the - runtime type to match, or null if this is a catch-all - clause. Providing a type list enables to associate the catch region - with potentially several exception types, which is useful e.g. for - Ada. */ - -void -expand_start_catch (tree type_or_list) -{ - struct eh_region *c; - rtx note; - - if (! doing_eh (0)) - return; - - c = gen_eh_region_catch (cfun->eh->try_region, type_or_list); - cfun->eh->cur_region = c; - - c->label = gen_label_rtx (); - emit_label (c->label); - - note = emit_note (NOTE_INSN_EH_REGION_BEG); - NOTE_EH_HANDLER (note) = c->region_number; -} - -/* End a catch clause. Control will resume after the try/catch block. */ - -void -expand_end_catch (void) -{ - if (! doing_eh (0)) - return; - - expand_eh_region_end (); - emit_jump (cfun->eh->try_region->u.try.continue_label); -} - -/* End a sequence of catch handlers for a try block. */ - -void -expand_end_all_catch (void) -{ - struct eh_region *try_region; - - if (! doing_eh (0)) - return; - - try_region = cfun->eh->try_region; - cfun->eh->try_region = try_region->u.try.prev_try; - - emit_label (try_region->u.try.continue_label); -} - -/* End an exception region for an exception type filter. ALLOWED is a - TREE_LIST of types to be matched by the runtime. FAILURE is an - expression to invoke if a mismatch occurs. - - ??? We could use these semantics for calls to rethrow, too; if we can - see the surrounding catch clause, we know that the exception we're - rethrowing satisfies the "filter" of the catch type. */ - -void -expand_eh_region_end_allowed (tree allowed, tree failure) -{ - struct eh_region *region; - rtx around_label; - - if (! doing_eh (0)) - return; - - region = expand_eh_region_end (); - region->type = ERT_ALLOWED_EXCEPTIONS; - region->u.allowed.type_list = allowed; - region->label = gen_label_rtx (); - - for (; allowed ; allowed = TREE_CHAIN (allowed)) - add_type_for_runtime (TREE_VALUE (allowed)); - - /* We must emit the call to FAILURE here, so that if this function - throws a different exception, that it will be processed by the - correct region. */ - - around_label = gen_label_rtx (); - emit_jump (around_label); - - emit_label (region->label); - expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL); - /* We must adjust the stack before we reach the AROUND_LABEL because - the call to FAILURE does not occur on all paths to the - AROUND_LABEL. */ - do_pending_stack_adjust (); - - emit_label (around_label); -} - -/* End an exception region for a must-not-throw filter. FAILURE is an - expression invoke if an uncaught exception propagates this far. - - This is conceptually identical to expand_eh_region_end_allowed with - an empty allowed list (if you passed "std::terminate" instead of - "__cxa_call_unexpected"), but they are represented differently in - the C++ LSDA. */ - -void -expand_eh_region_end_must_not_throw (tree failure) -{ - struct eh_region *region; - rtx around_label; - - if (! doing_eh (0)) - return; - - region = expand_eh_region_end (); - region->type = ERT_MUST_NOT_THROW; - region->label = gen_label_rtx (); - - /* We must emit the call to FAILURE here, so that if this function - throws a different exception, that it will be processed by the - correct region. */ - - around_label = gen_label_rtx (); - emit_jump (around_label); - - emit_label (region->label); - expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL); - - emit_label (around_label); -} - -/* End an exception region for a throw. No handling goes on here, - but it's the easiest way for the front-end to indicate what type - is being thrown. */ - -void -expand_eh_region_end_throw (tree type) -{ - struct eh_region *region; - - if (! doing_eh (0)) - return; - - region = expand_eh_region_end (); - region->type = ERT_THROW; - region->u.throw.type = type; -} - -/* End a fixup region. Within this region the cleanups for the immediately - enclosing region are _not_ run. This is used for goto cleanup to avoid - destroying an object twice. - - This would be an extraordinarily simple prospect, were it not for the - fact that we don't actually know what the immediately enclosing region - is. This surprising fact is because expand_cleanups is currently - generating a sequence that it will insert somewhere else. We collect - the proper notion of "enclosing" in convert_from_eh_region_ranges. */ - -void -expand_eh_region_end_fixup (tree handler) -{ - struct eh_region *fixup; - - if (! doing_eh (0)) - return; - - fixup = expand_eh_region_end (); - fixup->type = ERT_FIXUP; - fixup->u.fixup.cleanup_exp = handler; -} - /* Note that the current EH region (if any) may contain a throw, or a call to a function which itself may contain a throw. */ @@ -954,7 +625,7 @@ get_exception_filter (struct function *fun) rtx filter = fun->eh->filter; if (fun == cfun && ! filter) { - filter = gen_reg_rtx (word_mode); + filter = gen_reg_rtx (targetm.eh_return_filter_mode ()); fun->eh->filter = filter; } return filter; @@ -962,9 +633,7 @@ get_exception_filter (struct function *fun) /* This section is for the exception handling specific optimization pass. */ -/* Random access the exception region tree. It's just as simple to - collect the regions this way as in expand_eh_region_start, but - without having to realloc memory. */ +/* Random access the exception region tree. */ void collect_eh_region_array (void) @@ -1018,8 +687,7 @@ resolve_one_fixup_region (struct eh_region *fixup) && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp) break; } - if (j > n) - abort (); + gcc_assert (j <= n); real = cleanup->outer; if (real && real->type == ERT_FIXUP) @@ -1141,14 +809,12 @@ remove_unreachable_regions (rtx insns) if (r->resume) { - if (uid_region_num[INSN_UID (r->resume)]) - abort (); + gcc_assert (!uid_region_num[INSN_UID (r->resume)]); uid_region_num[INSN_UID (r->resume)] = i; } if (r->label) { - if (uid_region_num[INSN_UID (r->label)]) - abort (); + gcc_assert (!uid_region_num[INSN_UID (r->label)]); uid_region_num[INSN_UID (r->label)] = i; } } @@ -1217,7 +883,7 @@ convert_from_eh_region_ranges_1 (rtx *pinsns, int *orig_sp, int cur) for (insn = *pinsns; insn ; insn = next) { next = NEXT_INSN (insn); - if (GET_CODE (insn) == NOTE) + if (NOTE_P (insn)) { int kind = NOTE_LINE_NUMBER (insn); if (kind == NOTE_INSN_EH_REGION_BEG @@ -1258,7 +924,7 @@ convert_from_eh_region_ranges_1 (rtx *pinsns, int *orig_sp, int cur) /* Calls can always potentially throw exceptions, unless they have a REG_EH_REGION note with a value of 0 or less. Which should be the only possible kind so far. */ - && (GET_CODE (insn) == CALL_INSN + && (CALL_P (insn) /* If we wanted exceptions for non-call insns, then any may_trap_p instruction could throw. */ || (flag_non_call_exceptions @@ -1272,8 +938,7 @@ convert_from_eh_region_ranges_1 (rtx *pinsns, int *orig_sp, int cur) } } - if (sp != orig_sp) - abort (); + gcc_assert (sp == orig_sp); } static void @@ -1336,8 +1001,7 @@ add_ehl_entry (rtx label, struct eh_region *region) label. After landing pad creation, the exception handlers may share landing pads. This is ok, since maybe_remove_eh_handler only requires the 1-1 mapping before landing pad creation. */ - if (*slot && !cfun->eh->built_landing_pads) - abort (); + gcc_assert (!*slot || cfun->eh->built_landing_pads); *slot = entry; } @@ -1434,7 +1098,7 @@ duplicate_eh_region_1 (struct eh_region *o, struct inline_remap *map) n->u.throw.type = o->u.throw.type; default: - abort (); + gcc_unreachable (); } if (o->label) @@ -1442,8 +1106,7 @@ duplicate_eh_region_1 (struct eh_region *o, struct inline_remap *map) if (o->resume) { n->resume = map->insn_map[INSN_UID (o->resume)]; - if (n->resume == NULL) - abort (); + gcc_assert (n->resume); } return n; @@ -1744,7 +1407,7 @@ assign_filter_values (void) for (;tp_node; tp_node = TREE_CHAIN (tp_node)) { int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node)); - tree flt_node = build_int_2 (flt, 0); + tree flt_node = build_int_cst (NULL_TREE, flt); r->u.catch.filter_list = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list); @@ -1755,7 +1418,7 @@ assign_filter_values (void) /* Get a filter value for the NULL list also since it will need an action record anyway. */ int flt = add_ttypes_entry (ttypes, NULL); - tree flt_node = build_int_2 (flt, 0); + tree flt_node = build_int_cst (NULL_TREE, flt); r->u.catch.filter_list = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list); @@ -1786,15 +1449,18 @@ emit_to_new_bb_before (rtx seq, rtx insn) rtx last; basic_block bb; edge e; + edge_iterator ei; /* If there happens to be an fallthru edge (possibly created by cleanup_cfg call), we don't want it to go into newly created landing pad or other EH construct. */ - for (e = BLOCK_FOR_INSN (insn)->pred; e; e = e->pred_next) + for (ei = ei_start (BLOCK_FOR_INSN (insn)->preds); (e = ei_safe_edge (ei)); ) if (e->flags & EDGE_FALLTHRU) force_nonfallthru (e); + else + ei_next (&ei); last = emit_insn_before (seq, insn); - if (GET_CODE (last) == BARRIER) + if (BARRIER_P (last)) last = PREV_INSN (last); bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb); update_bb_for_insn (bb); @@ -1856,7 +1522,8 @@ build_post_landing_pads (void) emit_cmp_and_jump_insns (cfun->eh->filter, GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)), - EQ, NULL_RTX, word_mode, 0, c->label); + EQ, NULL_RTX, + targetm.eh_return_filter_mode (), 0, c->label); tp_node = TREE_CHAIN (tp_node); flt_node = TREE_CHAIN (flt_node); @@ -1888,7 +1555,8 @@ build_post_landing_pads (void) emit_cmp_and_jump_insns (cfun->eh->filter, GEN_INT (region->u.allowed.filter), - EQ, NULL_RTX, word_mode, 0, region->label); + EQ, NULL_RTX, + targetm.eh_return_filter_mode (), 0, region->label); /* We delay the generation of the _Unwind_Resume until we generate landing pads. We emit a marker here so as to get good control @@ -1914,7 +1582,7 @@ build_post_landing_pads (void) break; default: - abort (); + gcc_unreachable (); } } } @@ -1958,8 +1626,8 @@ connect_post_landing_pads (void) emit_jump (outer->post_landing_pad); src = BLOCK_FOR_INSN (region->resume); dest = BLOCK_FOR_INSN (outer->post_landing_pad); - while (src->succ) - remove_edge (src->succ); + while (EDGE_COUNT (src->succs) > 0) + remove_edge (EDGE_SUCC (src, 0)); e = make_edge (src, dest, 0); e->probability = REG_BR_PROB_BASE; e->count = src->count; @@ -1985,8 +1653,7 @@ connect_post_landing_pads (void) end_sequence (); barrier = emit_insn_before (seq, region->resume); /* Avoid duplicate barrier. */ - if (GET_CODE (barrier) != BARRIER) - abort (); + gcc_assert (BARRIER_P (barrier)); delete_insn (barrier); delete_insn (region->resume); @@ -2066,7 +1733,8 @@ dw2_build_landing_pads (void) emit_move_insn (cfun->eh->exc_ptr, gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0))); emit_move_insn (cfun->eh->filter, - gen_rtx_REG (word_mode, EH_RETURN_DATA_REGNO (1))); + gen_rtx_REG (targetm.eh_return_filter_mode (), + EH_RETURN_DATA_REGNO (1))); seq = get_insns (); end_sequence (); @@ -2210,7 +1878,7 @@ sjlj_mark_call_sites (struct sjlj_lp_info *lp_info) rtx note, before, p; /* Reset value tracking at extended basic block boundaries. */ - if (GET_CODE (insn) == CODE_LABEL) + if (LABEL_P (insn)) last_call_site = -2; if (! INSN_P (insn)) @@ -2222,7 +1890,7 @@ sjlj_mark_call_sites (struct sjlj_lp_info *lp_info) /* Calls (and trapping insns) without notes are outside any exception handling region in this function. Mark them as no action. */ - if (GET_CODE (insn) == CALL_INSN + if (CALL_P (insn) || (flag_non_call_exceptions && may_trap_p (PATTERN (insn)))) this_call_site = -1; @@ -2244,7 +1912,7 @@ sjlj_mark_call_sites (struct sjlj_lp_info *lp_info) /* Don't separate a call from it's argument loads. */ before = insn; - if (GET_CODE (insn) == CALL_INSN) + if (CALL_P (insn)) before = find_first_parameter_load (insn, NULL_RTX); start_sequence (); @@ -2321,17 +1989,17 @@ sjlj_emit_function_enter (rtx dispatch_label) can_throw_internal instructions. */ for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin)) - if (GET_CODE (fn_begin) == NOTE + if (NOTE_P (fn_begin) && (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG || NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_BASIC_BLOCK)) break; if (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG) - insert_insn_on_edge (seq, ENTRY_BLOCK_PTR->succ); + insert_insn_on_edge (seq, EDGE_SUCC (ENTRY_BLOCK_PTR, 0)); else { - rtx last = BB_END (ENTRY_BLOCK_PTR->succ->dest); + rtx last = BB_END (EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest); for (; ; fn_begin = NEXT_INSN (fn_begin)) - if ((GET_CODE (fn_begin) == NOTE + if ((NOTE_P (fn_begin) && NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG) || fn_begin == last) break; @@ -2353,6 +2021,7 @@ sjlj_emit_function_exit (void) { rtx seq; edge e; + edge_iterator ei; start_sequence (); @@ -2366,7 +2035,7 @@ sjlj_emit_function_exit (void) post-dominates all can_throw_internal instructions. This is the last possible moment. */ - for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next) + FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) if (e->flags & EDGE_FALLTHRU) break; if (e) @@ -2376,20 +2045,20 @@ sjlj_emit_function_exit (void) /* Figure out whether the place we are supposed to insert libcall is inside the last basic block or after it. In the other case we need to emit to edge. */ - if (e->src->next_bb != EXIT_BLOCK_PTR) - abort (); - for (insn = NEXT_INSN (BB_END (e->src)); insn; insn = NEXT_INSN (insn)) - if (insn == cfun->eh->sjlj_exit_after) - break; - if (insn) - insert_insn_on_edge (seq, e); - else + gcc_assert (e->src->next_bb == EXIT_BLOCK_PTR); + for (insn = BB_HEAD (e->src); ; insn = NEXT_INSN (insn)) { - insn = cfun->eh->sjlj_exit_after; - if (GET_CODE (insn) == CODE_LABEL) - insn = NEXT_INSN (insn); - emit_insn_after (seq, insn); + if (insn == cfun->eh->sjlj_exit_after) + { + if (LABEL_P (insn)) + insn = NEXT_INSN (insn); + emit_insn_after (seq, insn); + return; + } + if (insn == BB_END (e->src)) + break; } + insert_insn_on_edge (seq, e); } } @@ -2509,8 +2178,6 @@ finish_eh_generation (void) connect many of the handlers, and then type information will not be effective. Still, this is a win over previous implementations. */ - cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL); - /* These registers are used by the landing pads. Make sure they have been generated. */ get_exception_pointer (cfun); @@ -2535,21 +2202,22 @@ finish_eh_generation (void) commit_edge_insertions (); FOR_EACH_BB (bb) { - edge e, next; + edge e; + edge_iterator ei; bool eh = false; - for (e = bb->succ; e; e = next) + for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) { - next = e->succ_next; if (e->flags & EDGE_EH) { remove_edge (e); eh = true; } + else + ei_next (&ei); } if (eh) rtl_make_eh_edge (NULL, bb, BB_END (bb)); } - cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL); } static hashval_t @@ -2588,8 +2256,7 @@ remove_exception_handler_label (rtx label) tmp.label = label; slot = (struct ehl_map_entry **) htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT); - if (! slot) - abort (); + gcc_assert (slot); htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot); } @@ -2612,9 +2279,13 @@ remove_eh_handler (struct eh_region *region) cfun->eh->region_array[region->region_number] = outer; if (region->aka) { - int i; - EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, - { cfun->eh->region_array[i] = outer; }); + unsigned i; + bitmap_iterator bi; + + EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, bi) + { + cfun->eh->region_array[i] = outer; + } } if (outer) @@ -2622,7 +2293,7 @@ remove_eh_handler (struct eh_region *region) if (!outer->aka) outer->aka = BITMAP_GGC_ALLOC (); if (region->aka) - bitmap_a_or_b (outer->aka, outer->aka, region->aka); + bitmap_ior_into (outer->aka, region->aka); bitmap_set_bit (outer->aka, region->region_number); } @@ -2660,8 +2331,7 @@ remove_eh_handler (struct eh_region *region) try->type == ERT_CATCH; try = try->next_peer) continue; - if (try->type != ERT_TRY) - abort (); + gcc_assert (try->type == ERT_TRY); next = region->u.catch.next_catch; prev = region->u.catch.prev_catch; @@ -2972,10 +2642,11 @@ reachable_next_level (struct eh_region *region, tree type_thrown, case ERT_FIXUP: case ERT_UNKNOWN: /* Shouldn't see these here. */ + gcc_unreachable (); break; + default: + gcc_unreachable (); } - - abort (); } /* Invoke CALLBACK on each region reachable from REGION_NUMBER. */ @@ -3050,7 +2721,7 @@ reachable_handlers (rtx insn) rtx handlers = NULL; int region_number; - if (GET_CODE (insn) == JUMP_INSN + if (JUMP_P (insn) && GET_CODE (PATTERN (insn)) == RESX) { region_number = XINT (PATTERN (insn), 0); @@ -3114,12 +2785,12 @@ can_throw_internal (rtx insn) if (! INSN_P (insn)) return false; - if (GET_CODE (insn) == JUMP_INSN + if (JUMP_P (insn) && GET_CODE (PATTERN (insn)) == RESX && XINT (PATTERN (insn), 0) > 0) return can_throw_internal_1 (XINT (PATTERN (insn), 0)); - if (GET_CODE (insn) == INSN + if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE) insn = XVECEXP (PATTERN (insn), 0, 0); @@ -3166,7 +2837,7 @@ can_throw_external (rtx insn) if (! INSN_P (insn)) return false; - if (GET_CODE (insn) == INSN + if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE) insn = XVECEXP (PATTERN (insn), 0, 0); @@ -3178,7 +2849,7 @@ can_throw_external (rtx insn) assume it might throw. Given that the front end and middle ends mark known NOTHROW functions, this isn't so wildly inaccurate. */ - return (GET_CODE (insn) == CALL_INSN + return (CALL_P (insn) || (flag_non_call_exceptions && may_trap_p (PATTERN (insn)))); } @@ -3188,14 +2859,14 @@ can_throw_external (rtx insn) return can_throw_external_1 (INTVAL (XEXP (note, 0))); } -/* Set current_function_nothrow and cfun->all_throwers_are_sibcalls. */ +/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */ void set_nothrow_function_flags (void) { rtx insn; - current_function_nothrow = 1; + TREE_NOTHROW (current_function_decl) = 1; /* Assume cfun->all_throwers_are_sibcalls until we encounter something that can throw an exception. We specifically exempt @@ -3211,9 +2882,9 @@ set_nothrow_function_flags (void) for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) if (can_throw_external (insn)) { - current_function_nothrow = 0; + TREE_NOTHROW (current_function_decl) = 0; - if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn)) + if (!CALL_P (insn) || !SIBLING_CALL_P (insn)) { cfun->all_throwers_are_sibcalls = 0; return; @@ -3224,9 +2895,9 @@ set_nothrow_function_flags (void) insn = XEXP (insn, 1)) if (can_throw_external (insn)) { - current_function_nothrow = 0; + TREE_NOTHROW (current_function_decl) = 0; - if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn)) + if (!CALL_P (insn) || !SIBLING_CALL_P (insn)) { cfun->all_throwers_are_sibcalls = 0; return; @@ -3260,7 +2931,7 @@ expand_builtin_eh_return_data_regno (tree arglist) if (TREE_CODE (which) != INTEGER_CST) { - error ("argument of `__builtin_eh_return_regno' must be constant"); + error ("argument of %<__builtin_eh_return_regno%> must be constant"); return constm1_rtx; } @@ -3589,7 +3260,7 @@ collect_one_action_chain (htab_t ar_hash, struct eh_region *region) return collect_one_action_chain (ar_hash, region->outer); default: - abort (); + gcc_unreachable (); } } @@ -3646,14 +3317,14 @@ convert_to_eh_region_ranges (void) rtx this_landing_pad; insn = iter; - if (GET_CODE (insn) == INSN + if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE) insn = XVECEXP (PATTERN (insn), 0, 0); note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); if (!note) { - if (! (GET_CODE (insn) == CALL_INSN + if (! (CALL_P (insn) || (flag_non_call_exceptions && may_trap_p (PATTERN (insn))))) continue; @@ -3816,8 +3487,6 @@ sjlj_size_of_call_site_table (void) static void dw2_output_call_site_table (void) { - const char *const function_start_lab - = IDENTIFIER_POINTER (current_function_func_begin_label); int n = cfun->eh->call_site_data_used; int i; @@ -3840,21 +3509,25 @@ dw2_output_call_site_table (void) /* ??? Perhaps use attr_length to choose data1 or data2 instead of data4 if the function is small enough. */ #ifdef HAVE_AS_LEB128 - dw2_asm_output_delta_uleb128 (reg_start_lab, function_start_lab, + dw2_asm_output_delta_uleb128 (reg_start_lab, + current_function_func_begin_label, "region %d start", i); dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab, "length"); if (cs->landing_pad) - dw2_asm_output_delta_uleb128 (landing_pad_lab, function_start_lab, + dw2_asm_output_delta_uleb128 (landing_pad_lab, + current_function_func_begin_label, "landing pad"); else dw2_asm_output_data_uleb128 (0, "landing pad"); #else - dw2_asm_output_delta (4, reg_start_lab, function_start_lab, + dw2_asm_output_delta (4, reg_start_lab, + current_function_func_begin_label, "region %d start", i); dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length"); if (cs->landing_pad) - dw2_asm_output_delta (4, landing_pad_lab, function_start_lab, + dw2_asm_output_delta (4, landing_pad_lab, + current_function_func_begin_label, "landing pad"); else dw2_asm_output_data (4, 0, "landing pad"); @@ -3928,7 +3601,8 @@ output_function_exception_table (void) if (! cfun->uses_eh_lsda) return; -#ifdef IA64_UNWIND_INFO +#ifdef TARGET_UNWIND_INFO + /* TODO: Move this into target file. */ fputs ("\t.personality\t", asm_out_file); output_addr_const (asm_out_file, eh_personality_libfunc); fputs ("\n\t.handlerdata\n", asm_out_file); @@ -4092,8 +3766,8 @@ output_function_exception_table (void) cgraph_varpool_mark_needed_node (node); } } - else if (TREE_CODE (type) != INTEGER_CST) - abort (); + else + gcc_assert (TREE_CODE (type) == INTEGER_CST); } if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)