OSDN Git Service

2010-04-27 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / except.c
index c916a18..fccfb73 100644 (file)
@@ -1,6 +1,6 @@
 /* Implements exception handling.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Mike Stump <mrs@cygnus.com>.
 
@@ -48,7 +48,7 @@ along with GCC; see the file COPYING3.  If not see
    a given statement does throw.  During this lowering process,
    we create an EH_LANDING_PAD node for each EH_REGION that has
    some code within the function that needs to be executed if a
-   throw does happen.  We also create RESX statements that are 
+   throw does happen.  We also create RESX statements that are
    used to transfer control from an inner EH_REGION to an outer
    EH_REGION.  We also create EH_DISPATCH statements as placeholders
    for a runtime type comparison that should be made in order to
@@ -75,7 +75,7 @@ along with GCC; see the file COPYING3.  If not see
    handler for the exception must be within a function somewhere
    up the call chain, so we call back into the exception runtime
    (__builtin_unwind_resume).
-   
+
    During pass_expand (cfgexpand.c), we generate REG_EH_REGION notes
    that create an rtl to eh_region mapping that corresponds to the
    gimple to eh_region mapping that had been recorded in the
@@ -93,7 +93,7 @@ along with GCC; see the file COPYING3.  If not see
    frame are emitted at this time.
 
    During pass_convert_to_eh_region_ranges (except.c), we transform
-   the REG_EH_REGION notes attached to individual insns into 
+   the REG_EH_REGION notes attached to individual insns into
    non-overlapping ranges of insns bounded by NOTE_INSN_EH_REGION_BEG
    and NOTE_INSN_EH_REGION_END.  Each insn within such ranges has the
    same associated action within the exception region tree, meaning
@@ -153,9 +153,6 @@ along with GCC; see the file COPYING3.  If not see
    to the given failure handler.  */
 tree (*lang_protect_cleanup_actions) (void);
 
-/* Return true if type A catches type B.  */
-int (*lang_eh_type_covers) (tree a, tree b);
-
 static GTY(()) int call_site_base;
 static GTY ((param_is (union tree_node)))
   htab_t type_to_runtime_map;
@@ -369,6 +366,10 @@ gen_eh_region (enum eh_region_type type, eh_region outer)
   new_eh->index = VEC_length (eh_region, cfun->eh->region_array);
   VEC_safe_push (eh_region, gc, cfun->eh->region_array, new_eh);
 
+  /* Copy the language's notion of whether to use __cxa_end_cleanup.  */
+  if (targetm.arm_eabi_unwinder && lang_hooks.eh_use_cxa_end_cleanup)
+    new_eh->use_cxa_end_cleanup = true;
+
   return new_eh;
 }
 
@@ -548,8 +549,11 @@ duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
 
     case ERT_ALLOWED_EXCEPTIONS:
       new_r->u.allowed.type_list = old_r->u.allowed.type_list;
-      new_r->u.allowed.label
-       = data->label_map (old_r->u.allowed.label, data->label_map_data);
+      if (old_r->u.allowed.label)
+       new_r->u.allowed.label
+           = data->label_map (old_r->u.allowed.label, data->label_map_data);
+      else
+       new_r->u.allowed.label = NULL_TREE;
       break;
 
     case ERT_MUST_NOT_THROW:
@@ -573,6 +577,9 @@ duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
       EH_LANDING_PAD_NR (new_lp->post_landing_pad) = new_lp->index;
     }
 
+  /* Make sure to preserve the original use of __cxa_end_cleanup.  */
+  new_r->use_cxa_end_cleanup = old_r->use_cxa_end_cleanup;
+
   for (old_r = old_r->inner; old_r ; old_r = old_r->next_peer)
     duplicate_eh_regions_1 (data, old_r, new_r);
 }
@@ -601,7 +608,7 @@ duplicate_eh_regions (struct function *ifun,
   data.eh_map = pointer_map_create ();
 
   outer_region = get_eh_region_from_lp_number (outer_lp);
-  
+
   /* Copy all the regions in the subtree.  */
   if (copy_region)
     duplicate_eh_regions_1 (&data, copy_region, outer_region);
@@ -964,6 +971,7 @@ dw2_build_landing_pads (void)
 
       lp->landing_pad = gen_label_rtx ();
       emit_label (lp->landing_pad);
+      LABEL_PRESERVE_P (lp->landing_pad) = 1;
 
 #ifdef HAVE_exception_receiver
       if (HAVE_exception_receiver)
@@ -1144,7 +1152,7 @@ sjlj_emit_function_enter (rtx dispatch_label)
 
 #ifdef DONT_USE_BUILTIN_SETJMP
   {
-    rtx x;
+    rtx x, last;
     x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
                                 TYPE_MODE (integer_type_node), 1,
                                 plus_constant (XEXP (fc, 0),
@@ -1152,7 +1160,12 @@ sjlj_emit_function_enter (rtx dispatch_label)
 
     emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
                             TYPE_MODE (integer_type_node), 0, dispatch_label);
-    add_reg_br_prob_note (get_insns (), REG_BR_PROB_BASE/100);
+    last = get_last_insn ();
+    if (JUMP_P (last) && any_condjump_p (last))
+      {
+        gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
+        add_reg_note (last, REG_BR_PROB, GEN_INT (REG_BR_PROB_BASE / 100));
+      }
   }
 #else
   expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
@@ -1455,7 +1468,7 @@ struct rtl_opt_pass pass_rtl_eh =
 {
  {
   RTL_PASS,
-  "eh",                                 /* name */
+  "rtl eh",                             /* name */
   gate_handle_eh,                       /* gate */
   rest_of_handle_eh,                   /* execute */
   NULL,                                 /* sub */
@@ -1480,7 +1493,7 @@ remove_eh_landing_pad (eh_landing_pad lp)
   for (pp = &lp->region->landing_pads; *pp != lp; pp = &(*pp)->next_lp)
     continue;
   *pp = lp->next_lp;
-  
+
   if (lp->post_landing_pad)
     EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
   VEC_replace (eh_landing_pad, cfun->eh->lp_array, lp->index, NULL);
@@ -1545,7 +1558,7 @@ for_each_eh_label (void (*callback) (rtx))
 }
 \f
 /* Create the REG_EH_REGION note for INSN, given its ECF_FLAGS for a
-   call insn. 
+   call insn.
 
    At the gimple level, we use LP_NR
        > 0 : The statement transfers to landing pad LP_NR
@@ -1825,7 +1838,7 @@ can_nonlocal_goto (const_rtx insn)
 \f
 /* Set TREE_NOTHROW and crtl->all_throwers_are_sibcalls.  */
 
-unsigned int
+static unsigned int
 set_nothrow_function_flags (void)
 {
   rtx insn;
@@ -1882,7 +1895,7 @@ set_nothrow_function_flags (void)
       struct cgraph_edge *e;
       for (e = node->callers; e; e = e->next_caller)
         e->can_throw_external = false;
-      TREE_NOTHROW (current_function_decl) = 1;
+      cgraph_set_nothrow_flag (node, true);
 
       if (dump_file)
        fprintf (dump_file, "Marking function nothrow: %s\n\n",
@@ -2879,7 +2892,14 @@ output_ttype (tree type, int tt_format, int tt_format_size)
     {
       struct varpool_node *node;
 
-      type = lookup_type_for_runtime (type);
+      /* FIXME lto.  pass_ipa_free_lang_data changes all types to
+        runtime types so TYPE should already be a runtime type
+        reference.  When pass_ipa_free_lang data is made a default
+        pass, we can then remove the call to lookup_type_for_runtime
+        below.  */
+      if (TYPE_P (type))
+       type = lookup_type_for_runtime (type);
+
       value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
 
       /* Let cgraph know that the rtti decl is used.  Not all of the