#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. */
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);
}
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;
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);
}
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)
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++;
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++;
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);
}
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;
}
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;
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'
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);
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;
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:
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)