OSDN Git Service

Fix another mips typo.
[pf3gnuchains/gcc-fork.git] / gcc / tree-eh.c
index 9666e99..a231f29 100644 (file)
@@ -37,8 +37,15 @@ Boston, MA 02111-1307, USA.  */
 #include "langhooks.h"
 #include "ggc.h"
 
-/* HACK */
-extern int using_eh_for_cleanups_p;
+\f
+/* Nonzero if we are using EH to handle cleanups.  */
+static int using_eh_for_cleanups_p = 0;
+
+void
+using_eh_for_cleanups (void)
+{
+  using_eh_for_cleanups_p = 1;
+}
 \f
 /* Misc functions used in this file.  */
 
@@ -825,7 +832,8 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
       tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
 
       x = build1 (RESX_EXPR, void_type_node,
-                 build_int_2 (get_eh_region_number (tf->region), 0));
+                 build_int_cst (NULL_TREE,
+                                get_eh_region_number (tf->region), 0));
       tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
     }
 
@@ -931,7 +939,8 @@ lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
       append_to_statement_list (finally, tf->top_p);
       
       x = build1 (RESX_EXPR, void_type_node,
-                 build_int_2 (get_eh_region_number (tf->region), 0));
+                 build_int_cst (NULL_TREE,
+                                get_eh_region_number (tf->region), 0));
       append_to_statement_list (x, tf->top_p);
 
       return;
@@ -1019,7 +1028,8 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
       append_to_statement_list (x, &new_stmt);
 
       x = build1 (RESX_EXPR, void_type_node,
-                 build_int_2 (get_eh_region_number (tf->region), 0));
+                 build_int_cst (NULL_TREE,
+                                get_eh_region_number (tf->region), 0));
       append_to_statement_list (x, &new_stmt);
     }
 
@@ -1127,7 +1137,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
   if (tf->may_fallthru)
     {
       x = build (MODIFY_EXPR, void_type_node, finally_tmp,
-                build_int_2 (fallthru_index, 0));
+                build_int_cst (NULL_TREE, fallthru_index, 0));
       append_to_statement_list (x, tf->top_p);
 
       if (tf->may_throw)
@@ -1138,7 +1148,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
 
 
       last_case = build (CASE_LABEL_EXPR, void_type_node,
-                        build_int_2 (fallthru_index, 0), NULL,
+                        build_int_cst (NULL_TREE, fallthru_index, 0), NULL,
                         create_artificial_label ());
       TREE_VEC_ELT (case_label_vec, last_case_index) = last_case;
       last_case_index++;
@@ -1157,11 +1167,11 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
       append_to_statement_list (x, tf->top_p);
 
       x = build (MODIFY_EXPR, void_type_node, finally_tmp,
-                build_int_2 (eh_index, 0));
+                build_int_cst (NULL_TREE, eh_index, 0));
       append_to_statement_list (x, tf->top_p);
 
       last_case = build (CASE_LABEL_EXPR, void_type_node,
-                        build_int_2 (eh_index, 0), NULL,
+                        build_int_cst (NULL_TREE, eh_index, 0), NULL,
                         create_artificial_label ());
       TREE_VEC_ELT (case_label_vec, last_case_index) = last_case;
       last_case_index++;
@@ -1169,7 +1179,8 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
       x = build (LABEL_EXPR, void_type_node, CASE_LABEL (last_case));
       append_to_statement_list (x, &switch_body);
       x = build1 (RESX_EXPR, void_type_node,
-                 build_int_2 (get_eh_region_number (tf->region), 0));
+                 build_int_cst (NULL_TREE,
+                                get_eh_region_number (tf->region), 0));
       append_to_statement_list (x, &switch_body);
     }
 
@@ -1191,14 +1202,14 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
       if (q->index < 0)
        {
          mod = build (MODIFY_EXPR, void_type_node, finally_tmp,
-                      build_int_2 (return_index, 0));
+                      build_int_cst (NULL_TREE, return_index, 0));
          do_return_redirection (q, finally_label, mod, &return_val);
          switch_id = return_index;
        }
       else
        {
          mod = build (MODIFY_EXPR, void_type_node, finally_tmp,
-                      build_int_2 (q->index, 0));
+                      build_int_cst (NULL_TREE, q->index, 0));
          do_goto_redirection (q, finally_label, mod);
          switch_id = q->index;
        }
@@ -1207,7 +1218,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
       if (!TREE_VEC_ELT (case_label_vec, case_index))
        {
          last_case = build (CASE_LABEL_EXPR, void_type_node,
-                            build_int_2 (switch_id, 0), NULL,
+                            build_int_cst (NULL_TREE, switch_id, 0), NULL,
                             create_artificial_label ());
          TREE_VEC_ELT (case_label_vec, case_index) = last_case;
 
@@ -1705,7 +1716,8 @@ tree_could_trap_p (tree expr)
   bool honor_nans = false;
   bool honor_snans = false;
   bool fp_operation = false;
-  tree t;
+  bool honor_trapv = false;
+  tree t, base, idx;
 
   if (TREE_CODE_CLASS (code) == '<'
       || TREE_CODE_CLASS (code) == '1'
@@ -1718,18 +1730,41 @@ tree_could_trap_p (tree expr)
          honor_nans = flag_trapping_math && !flag_finite_math_only;
          honor_snans = flag_signaling_nans != 0;
        }
+      else if (INTEGRAL_TYPE_P (t) && TYPE_TRAP_SIGNED (t))
+       honor_trapv = true;
     }
 
+ restart:
   switch (code)
     {
-    case ARRAY_REF:
-    case ARRAY_RANGE_REF:
     case COMPONENT_REF:
     case REALPART_EXPR:
     case IMAGPART_EXPR:
     case BIT_FIELD_REF:
-      t = get_base_address (expr);
-      return !t || tree_could_trap_p (t);
+    case WITH_SIZE_EXPR:
+      expr = TREE_OPERAND (expr, 0);
+      code = TREE_CODE (expr);
+      goto restart;
+
+    case ARRAY_RANGE_REF:
+      /* Let us be conservative here for now.  We might be checking bounds of
+        the access similarly to the case below.  */
+      if (!TREE_THIS_NOTRAP (expr))
+       return true;
+
+      base = TREE_OPERAND (expr, 0);
+      return tree_could_trap_p (base);
+
+    case ARRAY_REF:
+      base = TREE_OPERAND (expr, 0);
+      idx = TREE_OPERAND (expr, 1);
+      if (tree_could_trap_p (base))
+       return true;
+
+      if (TREE_THIS_NOTRAP (expr))
+       return false;
+
+      return !in_array_bounds_p (expr);
 
     case INDIRECT_REF:
       return !TREE_THIS_NOTRAP (expr);
@@ -1747,7 +1782,7 @@ tree_could_trap_p (tree expr)
     case ROUND_MOD_EXPR:
     case TRUNC_MOD_EXPR:
     case RDIV_EXPR:
-      if (honor_snans)
+      if (honor_snans || honor_trapv)
        return true;
       if (fp_operation && flag_trapping_math)
        return true;
@@ -1786,7 +1821,19 @@ tree_could_trap_p (tree expr)
     case NEGATE_EXPR:
     case ABS_EXPR:
     case CONJ_EXPR:
-      /* These operations don't trap even with floating point.  */
+      /* These operations don't trap with floating point.  */
+      if (honor_trapv)
+       return true;
+      return false;
+
+    case PLUS_EXPR:
+    case MINUS_EXPR:
+    case MULT_EXPR:
+      /* Any floating arithmetic may trap.  */
+      if (fp_operation && flag_trapping_math)
+       return true;
+      if (honor_trapv)
+       return true;
       return false;
 
     default:
@@ -1810,6 +1857,8 @@ tree_could_throw_p (tree t)
       t = TREE_OPERAND (t, 1);
     }
 
+  if (TREE_CODE (t) == WITH_SIZE_EXPR)
+    t = TREE_OPERAND (t, 0);
   if (TREE_CODE (t) == CALL_EXPR)
     return (call_expr_flags (t) & ECF_NOTHROW) == 0;
   if (flag_non_call_exceptions)