OSDN Git Service

contrib:
[pf3gnuchains/gcc-fork.git] / gcc / except.c
index 627c32f..5c666d4 100644 (file)
@@ -463,7 +463,6 @@ static void start_dynamic_cleanup   PARAMS ((tree, tree));
 static void start_dynamic_handler      PARAMS ((void));
 static void expand_rethrow     PARAMS ((rtx));
 static void output_exception_table_entry       PARAMS ((FILE *, int));
-static int can_throw           PARAMS ((rtx));
 static rtx scan_region         PARAMS ((rtx, int, int *));
 static void eh_regs            PARAMS ((rtx *, rtx *, rtx *, int));
 static void set_insn_eh_region PARAMS ((rtx *, int));
@@ -501,18 +500,14 @@ create_rethrow_ref (region_num)
      int region_num;
 {
   rtx def;
-  char *ptr;
+  const char *ptr;
   char buf[60];
 
-  push_obstacks_nochange ();
-  end_temporary_allocation ();
-
   ASM_GENERATE_INTERNAL_LABEL (buf, "LRTH", region_num);
-  ptr = ggc_alloc_string (buf, -1);
+  ptr = ggc_strdup (buf);
   def = gen_rtx_SYMBOL_REF (Pmode, ptr);
   SYMBOL_REF_NEED_ADJUST (def) = 1;
 
-  pop_obstacks ();
   return def;
 }
 
@@ -677,19 +672,40 @@ static void
 receive_exception_label (handler_label)
      rtx handler_label;
 {
+  rtx around_label = NULL_RTX;
+
+  if (! flag_new_exceptions || exceptions_via_longjmp)
+    {
+      around_label = gen_label_rtx ();
+      emit_jump (around_label);
+      emit_barrier ();
+    }
+
   emit_label (handler_label);
   
-#ifdef HAVE_exception_receiver
   if (! exceptions_via_longjmp)
-    if (HAVE_exception_receiver)
-      emit_insn (gen_exception_receiver ());
+    {
+#ifdef HAVE_exception_receiver
+      if (HAVE_exception_receiver)
+       emit_insn (gen_exception_receiver ());
+      else
 #endif
-
 #ifdef HAVE_nonlocal_goto_receiver
-  if (! exceptions_via_longjmp)
-    if (HAVE_nonlocal_goto_receiver)
-      emit_insn (gen_nonlocal_goto_receiver ());
+      if (HAVE_nonlocal_goto_receiver)
+       emit_insn (gen_nonlocal_goto_receiver ());
+      else
+#endif
+       { /* Nothing */ }
+    }
+  else
+    {
+#ifndef DONT_USE_BUILTIN_SETJMP
+      expand_builtin_setjmp_receiver (handler_label);
 #endif
+    }
+
+  if (around_label)
+    emit_label (around_label);
 }
 
 
@@ -932,7 +948,8 @@ clear_function_eh_region ()
         next = ptr->next;
         free (ptr);
       }
-  free (function_eh_regions);
+  if (function_eh_regions)
+    free (function_eh_regions);
   num_func_eh_entries  = 0;
   current_func_eh_entry = 0;
 }
@@ -1104,10 +1121,6 @@ add_partial_entry (handler)
 {
   expand_eh_region_start ();
 
-  /* Make sure the entry is on the correct obstack.  */
-  push_obstacks_nochange ();
-  resume_temporary_allocation ();
-
   /* Because this is a cleanup action, we may have to protect the handler
      with __terminate.  */
   handler = protect_with_terminate (handler);
@@ -1121,7 +1134,6 @@ add_partial_entry (handler)
   /* Add this entry to the front of the list.  */
   TREE_VALUE (protect_list) 
     = tree_cons (NULL_TREE, handler, TREE_VALUE (protect_list));
-  pop_obstacks ();
 }
 
 /* Emit code to get EH context to current function.  */
@@ -1136,8 +1148,6 @@ call_get_eh_context ()
     {
       tree fntype;
       fn = get_identifier ("__get_eh_context");
-      push_obstacks_nochange ();
-      end_temporary_allocation ();
       fntype = build_pointer_type (build_pointer_type
                                   (build_pointer_type (void_type_node)));
       fntype = build_function_type (fntype, NULL_TREE);
@@ -1146,9 +1156,8 @@ call_get_eh_context ()
       TREE_PUBLIC (fn) = 1;
       DECL_ARTIFICIAL (fn) = 1;
       TREE_READONLY (fn) = 1;
-      make_decl_rtl (fn, NULL_PTR, 1);
+      make_decl_rtl (fn, NULL_PTR);
       assemble_external (fn);
-      pop_obstacks ();
 
       ggc_add_tree_root (&fn, 1);
     }
@@ -1316,7 +1325,7 @@ static void
 start_dynamic_handler ()
 {
   rtx dhc, dcc;
-  rtx x, arg, buf;
+  rtx arg, buf;
   int size;
 
 #ifndef DONT_USE_BUILTIN_SETJMP
@@ -1363,19 +1372,17 @@ start_dynamic_handler ()
   buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2);
 
 #ifdef DONT_USE_BUILTIN_SETJMP
-  x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1,
-                              TYPE_MODE (integer_type_node), 1,
-                              buf, Pmode);
-  /* If we come back here for a catch, transfer control to the handler.  */
-  jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
-#else
   {
-    /* A label to continue execution for the no exception case.  */
-    rtx noex = gen_label_rtx();
-    x = expand_builtin_setjmp (buf, NULL_RTX, noex,
-                              ehstack.top->entry->exception_handler_label);
-    emit_label (noex);
+    rtx x;
+    x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_CONST,
+                                TYPE_MODE (integer_type_node), 1,
+                                buf, Pmode);
+    /* If we come back here for a catch, transfer control to the handler.  */
+    jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
   }
+#else
+  expand_builtin_setjmp_setup (buf,
+                              ehstack.top->entry->exception_handler_label);
 #endif
 
   /* We are committed to this, so update the handler chain.  */
@@ -1761,7 +1768,8 @@ start_catch_handler (rtime)
 
       /* Now issue the call, and branch around handler if needed */
       call_rtx = emit_library_call_value (eh_rtime_match_libfunc, NULL_RTX, 
-                                          0, TYPE_MODE (integer_type_node),
+                                          LCT_NORMAL,
+                                         TYPE_MODE (integer_type_node),
                                          1, rtime_address, Pmode);
 
       /* Did the function return true? */
@@ -2042,15 +2050,8 @@ expand_rethrow (label)
 void
 begin_protect_partials ()
 {
-  /* Put the entry on the function obstack.  */
-  push_obstacks_nochange ();
-  resume_temporary_allocation ();
-
   /* Push room for a new list.  */
   protect_list = tree_cons (NULL_TREE, NULL_TREE, protect_list);
-
-  /* We're done with the function obstack now.  */
-  pop_obstacks ();
 }
 
 /* End all the pending exception regions on protect_list. The handlers
@@ -2090,10 +2091,6 @@ protect_with_terminate (e)
     {
       tree handler, result;
 
-      /* All cleanups must be on the function_obstack.  */
-      push_obstacks_nochange ();
-      resume_temporary_allocation ();
-
       handler = make_node (RTL_EXPR);
       TREE_TYPE (handler) = void_type_node;
       RTL_EXPR_RTL (handler) = const0_rtx;
@@ -2111,8 +2108,6 @@ protect_with_terminate (e)
       TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
       TREE_READONLY (result) = TREE_READONLY (e);
 
-      pop_obstacks ();
-
       e = result;
     }
 
@@ -2298,7 +2293,8 @@ set_exception_version_code (code)
 void
 free_exception_table ()
 {
-  free (eh_table);
+  if (eh_table)
+    free (eh_table);
   clear_function_eh_region ();
 }
   
@@ -2605,7 +2601,8 @@ mark_eh_status (eh)
   mark_eh_queue (eh->x_ehqueue);
   ggc_mark_rtx (eh->x_catch_clauses);
 
-  lang_mark_false_label_stack (eh->x_false_label_stack);
+  if (lang_mark_false_label_stack)
+    (*lang_mark_false_label_stack) (eh->x_false_label_stack);
   mark_tree_label_node (eh->x_caught_return_label_stack);
 
   ggc_mark_tree (eh->x_protect_list);
@@ -2688,12 +2685,11 @@ free_eh_status (f)
 }
 \f
 /* This section is for the exception handling specific optimization
-   pass.  First are the internal routines, and then the main
-   optimization pass.  */
+   pass.  */
 
 /* Determine if the given INSN can throw an exception.  */
 
-static int
+int
 can_throw (insn)
      rtx insn;
 {