Commit 73cd514a by Eric Botcazou Committed by Eric Botcazou

trans.c (gnat_to_gnu): Convert the count to the unsigned version of its base…

trans.c (gnat_to_gnu): Convert the count to the unsigned version of its base type before proceeding.

	* gcc-interface/trans.c (gnat_to_gnu) <Shift operations>: Convert the
	count to the unsigned version of its base type before proceeding.

From-SVN: r271646
parent 3aad84a4
2019-05-27 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (gnat_to_gnu) <Shift operations>: Convert the
count to the unsigned version of its base type before proceeding.
2019-05-16 Martin Sebor <msebor@redhat.com> 2019-05-16 Martin Sebor <msebor@redhat.com>
* gcc-interface/trans.c (check_inlining_for_nested_subprog): Quote * gcc-interface/trans.c (check_inlining_for_nested_subprog): Quote
......
...@@ -7422,7 +7422,7 @@ gnat_to_gnu (Node_Id gnat_node) ...@@ -7422,7 +7422,7 @@ gnat_to_gnu (Node_Id gnat_node)
enum tree_code code = gnu_codes[kind]; enum tree_code code = gnu_codes[kind];
bool ignore_lhs_overflow = false; bool ignore_lhs_overflow = false;
location_t saved_location = input_location; location_t saved_location = input_location;
tree gnu_type; tree gnu_type, gnu_max_shift = NULL_TREE;
/* Fix operations set up for boolean types in GNU_CODES above. */ /* Fix operations set up for boolean types in GNU_CODES above. */
if (Is_Modular_Integer_Type (Underlying_Type (Etype (gnat_node)))) if (Is_Modular_Integer_Type (Underlying_Type (Etype (gnat_node))))
...@@ -7445,6 +7445,17 @@ gnat_to_gnu (Node_Id gnat_node) ...@@ -7445,6 +7445,17 @@ gnat_to_gnu (Node_Id gnat_node)
gnu_rhs = gnat_to_gnu (Right_Opnd (gnat_node)); gnu_rhs = gnat_to_gnu (Right_Opnd (gnat_node));
gnu_type = gnu_result_type = get_unpadded_type (Etype (gnat_node)); gnu_type = gnu_result_type = get_unpadded_type (Etype (gnat_node));
/* If this is a shift, take the count as unsigned since that is what
most machines do and will generate simpler adjustments below. */
if (IN (kind, N_Op_Shift))
{
tree gnu_count_type
= gnat_unsigned_type_for (get_base_type (TREE_TYPE (gnu_rhs)));
gnu_rhs = convert (gnu_count_type, gnu_rhs);
gnu_max_shift
= convert (TREE_TYPE (gnu_rhs), TYPE_SIZE (gnu_type));
}
/* Pending generic support for efficient vector logical operations in /* Pending generic support for efficient vector logical operations in
GCC, convert vectors to their representative array type view and GCC, convert vectors to their representative array type view and
fallthrough. */ fallthrough. */
...@@ -7468,25 +7479,20 @@ gnat_to_gnu (Node_Id gnat_node) ...@@ -7468,25 +7479,20 @@ gnat_to_gnu (Node_Id gnat_node)
/* If this is a shift whose count is not guaranteed to be correct, /* If this is a shift whose count is not guaranteed to be correct,
we need to adjust the shift count. */ we need to adjust the shift count. */
if (IN (kind, N_Op_Shift) && !Shift_Count_OK (gnat_node)) if ((kind == N_Op_Rotate_Left || kind == N_Op_Rotate_Right)
{ && !Shift_Count_OK (gnat_node))
tree gnu_count_type = get_base_type (TREE_TYPE (gnu_rhs)); gnu_rhs = build_binary_op (TRUNC_MOD_EXPR, TREE_TYPE (gnu_rhs),
tree gnu_max_shift gnu_rhs, gnu_max_shift);
= convert (gnu_count_type, TYPE_SIZE (gnu_type)); else if (kind == N_Op_Shift_Right_Arithmetic
&& !Shift_Count_OK (gnat_node))
if (kind == N_Op_Rotate_Left || kind == N_Op_Rotate_Right) gnu_rhs
gnu_rhs = build_binary_op (TRUNC_MOD_EXPR, gnu_count_type, = build_binary_op (MIN_EXPR, TREE_TYPE (gnu_rhs),
gnu_rhs, gnu_max_shift); build_binary_op (MINUS_EXPR,
else if (kind == N_Op_Shift_Right_Arithmetic) TREE_TYPE (gnu_rhs),
gnu_rhs gnu_max_shift,
= build_binary_op build_int_cst
(MIN_EXPR, gnu_count_type, (TREE_TYPE (gnu_rhs), 1)),
build_binary_op (MINUS_EXPR, gnu_rhs);
gnu_count_type,
gnu_max_shift,
build_int_cst (gnu_count_type, 1)),
gnu_rhs);
}
/* For right shifts, the type says what kind of shift to do, /* For right shifts, the type says what kind of shift to do,
so we may need to choose a different type. In this case, so we may need to choose a different type. In this case,
...@@ -7533,18 +7539,15 @@ gnat_to_gnu (Node_Id gnat_node) ...@@ -7533,18 +7539,15 @@ gnat_to_gnu (Node_Id gnat_node)
/* If this is a logical shift with the shift count not verified, /* If this is a logical shift with the shift count not verified,
we must return zero if it is too large. We cannot compensate we must return zero if it is too large. We cannot compensate
above in this case. */ beforehand in this case. */
if ((kind == N_Op_Shift_Left || kind == N_Op_Shift_Right) if ((kind == N_Op_Shift_Left || kind == N_Op_Shift_Right)
&& !Shift_Count_OK (gnat_node)) && !Shift_Count_OK (gnat_node))
gnu_result gnu_result
= build_cond_expr = build_cond_expr (gnu_type,
(gnu_type, build_binary_op (GE_EXPR, boolean_type_node,
build_binary_op (GE_EXPR, boolean_type_node, gnu_rhs, gnu_max_shift),
gnu_rhs, build_int_cst (gnu_type, 0),
convert (TREE_TYPE (gnu_rhs), gnu_result);
TYPE_SIZE (gnu_type))),
build_int_cst (gnu_type, 0),
gnu_result);
} }
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment