OSDN Git Service

* config/rs6000/rs6000.c (rs6000_va_arg): Replace SPLIT_COMPLEX_ARGS
[pf3gnuchains/gcc-fork.git] / gcc / except.c
index 70eb3b1..809f653 100644 (file)
@@ -602,10 +602,12 @@ expand_start_all_catch (void)
   emit_jump (region->u.try.continue_label);
 }
 
-/* Begin a catch clause.  TYPE is the type caught, a list of such types, 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.  */
+/* 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)
@@ -1046,7 +1048,18 @@ remove_unreachable_regions (rtx insns)
     }
 
   for (insn = insns; insn; insn = NEXT_INSN (insn))
-    reachable[uid_region_num[INSN_UID (insn)]] = true;
+    {
+      reachable[uid_region_num[INSN_UID (insn)]] = true;
+
+      if (GET_CODE (insn) == CALL_INSN
+         && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
+       for (i = 0; i < 3; i++)
+         {
+           rtx sub = XEXP (PATTERN (insn), i);
+           for (; sub ; sub = NEXT_INSN (sub))
+             reachable[uid_region_num[INSN_UID (sub)]] = true;
+         }
+    }
 
   for (i = cfun->eh->last_region_number; i > 0; --i)
     {
@@ -1411,7 +1424,7 @@ static hashval_t
 t2r_hash (const void *pentry)
 {
   tree entry = (tree) pentry;
-  return TYPE_HASH (TREE_PURPOSE (entry));
+  return TREE_HASH (TREE_PURPOSE (entry));
 }
 
 static void
@@ -1420,7 +1433,7 @@ add_type_for_runtime (tree type)
   tree *slot;
 
   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
-                                           TYPE_HASH (type), INSERT);
+                                           TREE_HASH (type), INSERT);
   if (*slot == NULL)
     {
       tree runtime = (*lang_eh_runtime_type) (type);
@@ -1434,7 +1447,7 @@ lookup_type_for_runtime (tree type)
   tree *slot;
 
   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
-                                           TYPE_HASH (type), NO_INSERT);
+                                           TREE_HASH (type), NO_INSERT);
 
   /* We should have always inserted the data earlier.  */
   return TREE_VALUE (*slot);
@@ -1465,7 +1478,7 @@ static hashval_t
 ttypes_filter_hash (const void *pentry)
 {
   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
-  return TYPE_HASH (entry->t);
+  return TREE_HASH (entry->t);
 }
 
 /* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
@@ -1492,12 +1505,12 @@ ehspec_filter_hash (const void *pentry)
   tree list;
 
   for (list = entry->t; list ; list = TREE_CHAIN (list))
-    h = (h << 5) + (h >> 27) + TYPE_HASH (TREE_VALUE (list));
+    h = (h << 5) + (h >> 27) + TREE_HASH (TREE_VALUE (list));
   return h;
 }
 
-/* Add TYPE to cfun->eh->ttype_data, using TYPES_HASH to speed
-   up the search.  Return the filter value to be used.  */
+/* Add TYPE (which may be NULL) to cfun->eh->ttype_data, using TYPES_HASH
+   to speed up the search.  Return the filter value to be used.  */
 
 static int
 add_ttypes_entry (htab_t ttypes_hash, tree type)
@@ -1505,7 +1518,7 @@ add_ttypes_entry (htab_t ttypes_hash, tree type)
   struct ttypes_filter **slot, *n;
 
   slot = (struct ttypes_filter **)
-    htab_find_slot_with_hash (ttypes_hash, type, TYPE_HASH (type), INSERT);
+    htab_find_slot_with_hash (ttypes_hash, type, TREE_HASH (type), INSERT);
 
   if ((n = *slot) == NULL)
     {
@@ -1637,7 +1650,14 @@ emit_to_new_bb_before (rtx seq, rtx insn)
 {
   rtx last;
   basic_block bb;
+  edge e;
 
+  /* 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)
+    if (e->flags & EDGE_FALLTHRU)
+      force_nonfallthru (e);
   last = emit_insn_before (seq, insn);
   if (GET_CODE (last) == BARRIER)
     last = PREV_INSN (last);