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>
* gcc-interface/trans.c (check_inlining_for_nested_subprog): Quote
......
......@@ -7422,7 +7422,7 @@ gnat_to_gnu (Node_Id gnat_node)
enum tree_code code = gnu_codes[kind];
bool ignore_lhs_overflow = false;
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. */
if (Is_Modular_Integer_Type (Underlying_Type (Etype (gnat_node))))
......@@ -7445,6 +7445,17 @@ gnat_to_gnu (Node_Id gnat_node)
gnu_rhs = gnat_to_gnu (Right_Opnd (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
GCC, convert vectors to their representative array type view and
fallthrough. */
......@@ -7468,25 +7479,20 @@ gnat_to_gnu (Node_Id gnat_node)
/* If this is a shift whose count is not guaranteed to be correct,
we need to adjust the shift count. */
if (IN (kind, N_Op_Shift) && !Shift_Count_OK (gnat_node))
{
tree gnu_count_type = get_base_type (TREE_TYPE (gnu_rhs));
tree gnu_max_shift
= convert (gnu_count_type, TYPE_SIZE (gnu_type));
if (kind == N_Op_Rotate_Left || kind == N_Op_Rotate_Right)
gnu_rhs = build_binary_op (TRUNC_MOD_EXPR, gnu_count_type,
gnu_rhs, gnu_max_shift);
else if (kind == N_Op_Shift_Right_Arithmetic)
gnu_rhs
= build_binary_op
(MIN_EXPR, gnu_count_type,
build_binary_op (MINUS_EXPR,
gnu_count_type,
gnu_max_shift,
build_int_cst (gnu_count_type, 1)),
gnu_rhs);
}
if ((kind == N_Op_Rotate_Left || kind == N_Op_Rotate_Right)
&& !Shift_Count_OK (gnat_node))
gnu_rhs = build_binary_op (TRUNC_MOD_EXPR, TREE_TYPE (gnu_rhs),
gnu_rhs, gnu_max_shift);
else if (kind == N_Op_Shift_Right_Arithmetic
&& !Shift_Count_OK (gnat_node))
gnu_rhs
= build_binary_op (MIN_EXPR, TREE_TYPE (gnu_rhs),
build_binary_op (MINUS_EXPR,
TREE_TYPE (gnu_rhs),
gnu_max_shift,
build_int_cst
(TREE_TYPE (gnu_rhs), 1)),
gnu_rhs);
/* For right shifts, the type says what kind of shift to do,
so we may need to choose a different type. In this case,
......@@ -7533,18 +7539,15 @@ gnat_to_gnu (Node_Id gnat_node)
/* If this is a logical shift with the shift count not verified,
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)
&& !Shift_Count_OK (gnat_node))
gnu_result
= build_cond_expr
(gnu_type,
build_binary_op (GE_EXPR, boolean_type_node,
gnu_rhs,
convert (TREE_TYPE (gnu_rhs),
TYPE_SIZE (gnu_type))),
build_int_cst (gnu_type, 0),
gnu_result);
= build_cond_expr (gnu_type,
build_binary_op (GE_EXPR, boolean_type_node,
gnu_rhs, gnu_max_shift),
build_int_cst (gnu_type, 0),
gnu_result);
}
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