gigi.h (enum standard_datatypes): Add new values ADT_sbitsize_one_node and ADT_sbitsize_unit_node.
* gcc-interface/gigi.h (enum standard_datatypes): Add new values ADT_sbitsize_one_node and ADT_sbitsize_unit_node. (sbitsize_one_node): New macro. (sbitsize_unit_node): Likewise. * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Subtype>: Fix latent bug in the computation of subrange_p. Fold wider_p predicate. (cannot_be_superflat_p): Use an explicitly signed 64-bit type to do the final comparison. (make_aligning_type): Build real negation and use sizetype throughout the offset computation. (maybe_pad_type): Do not issue the warning when the new size expression is too complex. (annotate_value) <INTEGER_CST>: Simplify code handling negative values. * gcc-interface/misc.c (gnat_init): Initialize sbitsize_one_node and sbitsize_unit_node. * gcc-interface/trans.c (Attribute_to_gnu) <Attr_Pool_Address>: Fold double negation. (gnat_to_gnu) <N_Free_Statement>: Likewise. * gcc-interface/utils.c (convert): Use sbitsize_unit_node. * gcc-interface/utils2.c (compare_arrays): Compute real lengths and use constants in sizetype. Remove dead code and tweak comments. Generate equality instead of inequality comparisons for zero length tests. From-SVN: r158461
This commit is contained in:
parent
80d56d040e
commit
1081f5a7c7
|
@ -1,3 +1,28 @@
|
|||
2010-04-17 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc-interface/gigi.h (enum standard_datatypes): Add new values
|
||||
ADT_sbitsize_one_node and ADT_sbitsize_unit_node.
|
||||
(sbitsize_one_node): New macro.
|
||||
(sbitsize_unit_node): Likewise.
|
||||
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Subtype>: Fix
|
||||
latent bug in the computation of subrange_p. Fold wider_p predicate.
|
||||
(cannot_be_superflat_p): Use an explicitly signed 64-bit type to do
|
||||
the final comparison.
|
||||
(make_aligning_type): Build real negation and use sizetype throughout
|
||||
the offset computation.
|
||||
(maybe_pad_type): Do not issue the warning when the new size expression
|
||||
is too complex.
|
||||
(annotate_value) <INTEGER_CST>: Simplify code handling negative values.
|
||||
* gcc-interface/misc.c (gnat_init): Initialize sbitsize_one_node and
|
||||
sbitsize_unit_node.
|
||||
* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Pool_Address>: Fold
|
||||
double negation.
|
||||
(gnat_to_gnu) <N_Free_Statement>: Likewise.
|
||||
* gcc-interface/utils.c (convert): Use sbitsize_unit_node.
|
||||
* gcc-interface/utils2.c (compare_arrays): Compute real lengths and use
|
||||
constants in sizetype. Remove dead code and tweak comments. Generate
|
||||
equality instead of inequality comparisons for zero length tests.
|
||||
|
||||
2010-04-16 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc-interface/gigi.h (gnat_init_decl_processing): Delete.
|
||||
|
|
|
@ -2115,11 +2115,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
const int prec_comp
|
||||
= compare_tree_int (TYPE_RM_SIZE (gnu_index_type),
|
||||
TYPE_PRECISION (sizetype));
|
||||
const bool subrange_p = (prec_comp < 0)
|
||||
|| (prec_comp == 0
|
||||
&& TYPE_UNSIGNED (gnu_index_type)
|
||||
== TYPE_UNSIGNED (sizetype));
|
||||
const bool wider_p = (prec_comp > 0);
|
||||
const bool subrange_p = (prec_comp < 0
|
||||
&& (TYPE_UNSIGNED (gnu_index_type)
|
||||
|| !TYPE_UNSIGNED (sizetype)))
|
||||
|| (prec_comp == 0
|
||||
&& TYPE_UNSIGNED (gnu_index_type)
|
||||
== TYPE_UNSIGNED (sizetype));
|
||||
tree gnu_orig_min = TYPE_MIN_VALUE (gnu_index_type);
|
||||
tree gnu_orig_max = TYPE_MAX_VALUE (gnu_index_type);
|
||||
tree gnu_min = convert (sizetype, gnu_orig_min);
|
||||
|
@ -2298,7 +2299,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
&& TREE_CODE (TREE_TYPE (gnu_index_type))
|
||||
!= INTEGER_TYPE)
|
||||
|| TYPE_BIASED_REPRESENTATION_P (gnu_index_type)
|
||||
|| wider_p)
|
||||
|| prec_comp > 0)
|
||||
need_index_type_struct = true;
|
||||
}
|
||||
|
||||
|
@ -5381,7 +5382,7 @@ cannot_be_superflat_p (Node_Id gnat_range)
|
|||
{
|
||||
Node_Id gnat_lb = Low_Bound (gnat_range), gnat_hb = High_Bound (gnat_range);
|
||||
Node_Id scalar_range;
|
||||
tree gnu_lb, gnu_hb;
|
||||
tree gnu_lb, gnu_hb, gnu_lb_minus_one;
|
||||
|
||||
/* If the low bound is not constant, try to find an upper bound. */
|
||||
while (Nkind (gnat_lb) != N_Integer_Literal
|
||||
|
@ -5401,19 +5402,23 @@ cannot_be_superflat_p (Node_Id gnat_range)
|
|||
|| Nkind (scalar_range) == N_Range))
|
||||
gnat_hb = Low_Bound (scalar_range);
|
||||
|
||||
if (!(Nkind (gnat_lb) == N_Integer_Literal
|
||||
&& Nkind (gnat_hb) == N_Integer_Literal))
|
||||
/* If we have failed to find constant bounds, punt. */
|
||||
if (Nkind (gnat_lb) != N_Integer_Literal
|
||||
|| Nkind (gnat_hb) != N_Integer_Literal)
|
||||
return false;
|
||||
|
||||
gnu_lb = UI_To_gnu (Intval (gnat_lb), bitsizetype);
|
||||
gnu_hb = UI_To_gnu (Intval (gnat_hb), bitsizetype);
|
||||
/* We need at least a signed 64-bit type to catch most cases. */
|
||||
gnu_lb = UI_To_gnu (Intval (gnat_lb), sbitsizetype);
|
||||
gnu_hb = UI_To_gnu (Intval (gnat_hb), sbitsizetype);
|
||||
if (TREE_OVERFLOW (gnu_lb) || TREE_OVERFLOW (gnu_hb))
|
||||
return false;
|
||||
|
||||
/* If the low bound is the smallest integer, nothing can be smaller. */
|
||||
gnu_lb = size_binop (MINUS_EXPR, gnu_lb, bitsize_one_node);
|
||||
if (TREE_OVERFLOW (gnu_lb))
|
||||
gnu_lb_minus_one = size_binop (MINUS_EXPR, gnu_lb, sbitsize_one_node);
|
||||
if (TREE_OVERFLOW (gnu_lb_minus_one))
|
||||
return true;
|
||||
|
||||
return (tree_int_cst_lt (gnu_hb, gnu_lb) == 0);
|
||||
return !tree_int_cst_lt (gnu_hb, gnu_lb_minus_one);
|
||||
}
|
||||
|
||||
/* Return true if GNU_EXPR is (essentially) the address of a CONSTRUCTOR. */
|
||||
|
@ -5876,7 +5881,6 @@ make_aligning_type (tree type, unsigned int align, tree size,
|
|||
/* We will be crafting a record type with one field at a position set to be
|
||||
the next multiple of ALIGN past record'address + room bytes. We use a
|
||||
record placeholder to express record'address. */
|
||||
|
||||
tree record_type = make_node (RECORD_TYPE);
|
||||
tree record = build0 (PLACEHOLDER_EXPR, record_type);
|
||||
|
||||
|
@ -5896,7 +5900,6 @@ make_aligning_type (tree type, unsigned int align, tree size,
|
|||
|
||||
Every length is in sizetype bytes there, except "pos" which has to be
|
||||
set as a bit position in the GCC tree for the record. */
|
||||
|
||||
tree room_st = size_int (room);
|
||||
tree vblock_addr_st = size_binop (PLUS_EXPR, record_addr_st, room_st);
|
||||
tree voffset_st, pos, field;
|
||||
|
@ -5911,13 +5914,11 @@ make_aligning_type (tree type, unsigned int align, tree size,
|
|||
/* Compute VOFFSET and then POS. The next byte position multiple of some
|
||||
alignment after some address is obtained by "and"ing the alignment minus
|
||||
1 with the two's complement of the address. */
|
||||
|
||||
voffset_st = size_binop (BIT_AND_EXPR,
|
||||
size_diffop (size_zero_node, vblock_addr_st),
|
||||
ssize_int ((align / BITS_PER_UNIT) - 1));
|
||||
fold_build1 (NEGATE_EXPR, sizetype, vblock_addr_st),
|
||||
size_int ((align / BITS_PER_UNIT) - 1));
|
||||
|
||||
/* POS = (ROOM + VOFFSET) * BIT_PER_UNIT, in bitsizetype. */
|
||||
|
||||
pos = size_binop (MULT_EXPR,
|
||||
convert (bitsizetype,
|
||||
size_binop (PLUS_EXPR, room_st, voffset_st)),
|
||||
|
@ -5936,7 +5937,6 @@ make_aligning_type (tree type, unsigned int align, tree size,
|
|||
consequences on the alignment computation, and create_field_decl would
|
||||
make one without this special argument, for instance because of the
|
||||
complex position expression. */
|
||||
|
||||
field = create_field_decl (get_identifier ("F"), type, record_type,
|
||||
1, size, pos, -1);
|
||||
TYPE_FIELDS (record_type) = field;
|
||||
|
@ -6287,6 +6287,7 @@ maybe_pad_type (tree type, tree size, unsigned int align,
|
|||
if (Present (gnat_entity)
|
||||
&& size
|
||||
&& TREE_CODE (size) != MAX_EXPR
|
||||
&& TREE_CODE (size) != COND_EXPR
|
||||
&& !operand_equal_p (size, orig_size, 0)
|
||||
&& !(TREE_CODE (size) == INTEGER_CST
|
||||
&& TREE_CODE (orig_size) == INTEGER_CST
|
||||
|
@ -7123,33 +7124,16 @@ annotate_value (tree gnu_size)
|
|||
if (TREE_OVERFLOW (gnu_size))
|
||||
return No_Uint;
|
||||
|
||||
/* This may have come from a conversion from some smaller type,
|
||||
so ensure this is in bitsizetype. */
|
||||
/* This may come from a conversion from some smaller type, so ensure
|
||||
this is in bitsizetype. */
|
||||
gnu_size = convert (bitsizetype, gnu_size);
|
||||
|
||||
/* For negative values, use NEGATE_EXPR of the supplied value. */
|
||||
/* For a negative value, use NEGATE_EXPR of the opposite. Such values
|
||||
appear in expressions containing aligning patterns. */
|
||||
if (tree_int_cst_sgn (gnu_size) < 0)
|
||||
{
|
||||
/* The ridiculous code below is to handle the case of the largest
|
||||
negative integer. */
|
||||
tree negative_size = size_diffop (bitsize_zero_node, gnu_size);
|
||||
bool adjust = false;
|
||||
tree temp;
|
||||
|
||||
if (TREE_OVERFLOW (negative_size))
|
||||
{
|
||||
negative_size
|
||||
= size_binop (MINUS_EXPR, bitsize_zero_node,
|
||||
size_binop (PLUS_EXPR, gnu_size,
|
||||
bitsize_one_node));
|
||||
adjust = true;
|
||||
}
|
||||
|
||||
temp = build1 (NEGATE_EXPR, bitsizetype, negative_size);
|
||||
if (adjust)
|
||||
temp = build2 (MINUS_EXPR, bitsizetype, temp, bitsize_one_node);
|
||||
|
||||
return annotate_value (temp);
|
||||
tree op_size = fold_build1 (NEGATE_EXPR, bitsizetype, gnu_size);
|
||||
return annotate_value (build1 (NEGATE_EXPR, bitsizetype, op_size));
|
||||
}
|
||||
|
||||
return UI_From_gnu (gnu_size);
|
||||
|
|
|
@ -356,9 +356,15 @@ enum standard_datatypes
|
|||
/* Type declaration node <==> typedef virtual void *T() */
|
||||
ADT_fdesc_type,
|
||||
|
||||
/* Null pointer for above type */
|
||||
/* Null pointer for above type. */
|
||||
ADT_null_fdesc,
|
||||
|
||||
/* Value 1 in signed bitsizetype. */
|
||||
ADT_sbitsize_one_node,
|
||||
|
||||
/* Value BITS_PER_UNIT in signed bitsizetype. */
|
||||
ADT_sbitsize_unit_node,
|
||||
|
||||
/* Function declaration nodes for run-time functions for allocating memory.
|
||||
Ada allocators cause calls to these functions to be generated. Malloc32
|
||||
is used only on 64bit systems needing to allocate 32bit memory. */
|
||||
|
@ -401,6 +407,8 @@ extern GTY(()) tree gnat_raise_decls[(int) LAST_REASON_CODE + 1];
|
|||
#define ptr_void_ftype gnat_std_decls[(int) ADT_ptr_void_ftype]
|
||||
#define fdesc_type_node gnat_std_decls[(int) ADT_fdesc_type]
|
||||
#define null_fdesc_node gnat_std_decls[(int) ADT_null_fdesc]
|
||||
#define sbitsize_one_node gnat_std_decls[(int) ADT_sbitsize_one_node]
|
||||
#define sbitsize_unit_node gnat_std_decls[(int) ADT_sbitsize_unit_node]
|
||||
#define malloc_decl gnat_std_decls[(int) ADT_malloc_decl]
|
||||
#define malloc32_decl gnat_std_decls[(int) ADT_malloc32_decl]
|
||||
#define free_decl gnat_std_decls[(int) ADT_free_decl]
|
||||
|
|
|
@ -407,6 +407,8 @@ gnat_init (void)
|
|||
SET_TYPE_RM_SIZE (boolean_type_node, bitsize_int (1));
|
||||
|
||||
build_common_tree_nodes_2 (0);
|
||||
sbitsize_one_node = sbitsize_int (1);
|
||||
sbitsize_unit_node = sbitsize_int (BITS_PER_UNIT);
|
||||
boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
|
||||
|
||||
ptr_void_type_node = build_pointer_type (void_type_node);
|
||||
|
|
|
@ -1356,15 +1356,9 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
|
|||
{
|
||||
tree gnu_char_ptr_type = build_pointer_type (char_type_node);
|
||||
tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
|
||||
tree gnu_byte_offset
|
||||
= convert (sizetype,
|
||||
size_diffop (size_zero_node, gnu_pos));
|
||||
gnu_byte_offset
|
||||
= fold_build1 (NEGATE_EXPR, sizetype, gnu_byte_offset);
|
||||
|
||||
gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
|
||||
gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
|
||||
gnu_ptr, gnu_byte_offset);
|
||||
gnu_ptr, gnu_pos);
|
||||
}
|
||||
|
||||
gnu_result = convert (gnu_result_type, gnu_ptr);
|
||||
|
@ -5399,15 +5393,9 @@ gnat_to_gnu (Node_Id gnat_node)
|
|||
{
|
||||
tree gnu_char_ptr_type = build_pointer_type (char_type_node);
|
||||
tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
|
||||
tree gnu_byte_offset
|
||||
= convert (sizetype,
|
||||
size_diffop (size_zero_node, gnu_pos));
|
||||
gnu_byte_offset
|
||||
= fold_build1 (NEGATE_EXPR, sizetype, gnu_byte_offset);
|
||||
|
||||
gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
|
||||
gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
|
||||
gnu_ptr, gnu_byte_offset);
|
||||
gnu_ptr, gnu_pos);
|
||||
}
|
||||
|
||||
gnu_result
|
||||
|
|
|
@ -4066,9 +4066,8 @@ convert (tree type, tree expr)
|
|||
tree bit_diff
|
||||
= size_diffop (bit_position (TYPE_FIELDS (TREE_TYPE (etype))),
|
||||
bit_position (TYPE_FIELDS (TREE_TYPE (type))));
|
||||
tree byte_diff = size_binop (CEIL_DIV_EXPR, bit_diff,
|
||||
sbitsize_int (BITS_PER_UNIT));
|
||||
|
||||
tree byte_diff
|
||||
= size_binop (CEIL_DIV_EXPR, bit_diff, sbitsize_unit_node);
|
||||
expr = build1 (NOP_EXPR, type, expr);
|
||||
TREE_CONSTANT (expr) = TREE_CONSTANT (TREE_OPERAND (expr, 0));
|
||||
if (integer_zerop (byte_diff))
|
||||
|
|
|
@ -260,28 +260,27 @@ compare_arrays (tree result_type, tree a1, tree a2)
|
|||
a2 = gnat_protect_expr (a2);
|
||||
|
||||
/* Process each dimension separately and compare the lengths. If any
|
||||
dimension has a size known to be zero, set SIZE_ZERO_P to 1 to
|
||||
suppress the comparison of the data. */
|
||||
dimension has a length known to be zero, set LENGTH_ZERO_P to true
|
||||
in order to suppress the comparison of the data at the end. */
|
||||
while (TREE_CODE (t1) == ARRAY_TYPE && TREE_CODE (t2) == ARRAY_TYPE)
|
||||
{
|
||||
tree lb1 = TYPE_MIN_VALUE (TYPE_DOMAIN (t1));
|
||||
tree ub1 = TYPE_MAX_VALUE (TYPE_DOMAIN (t1));
|
||||
tree lb2 = TYPE_MIN_VALUE (TYPE_DOMAIN (t2));
|
||||
tree ub2 = TYPE_MAX_VALUE (TYPE_DOMAIN (t2));
|
||||
tree bt = get_base_type (TREE_TYPE (lb1));
|
||||
tree length1 = fold_build2 (MINUS_EXPR, bt, ub1, lb1);
|
||||
tree length2 = fold_build2 (MINUS_EXPR, bt, ub2, lb2);
|
||||
tree length1 = size_binop (PLUS_EXPR, size_binop (MINUS_EXPR, ub1, lb1),
|
||||
size_one_node);
|
||||
tree length2 = size_binop (PLUS_EXPR, size_binop (MINUS_EXPR, ub2, lb2),
|
||||
size_one_node);
|
||||
tree comparison, this_a1_is_null, this_a2_is_null;
|
||||
tree nbt, tem;
|
||||
bool btem;
|
||||
|
||||
/* If the length of the first array is a constant, swap our operands
|
||||
unless the length of the second array is the constant zero.
|
||||
Note that we have set the `length' values to the length - 1. */
|
||||
if (TREE_CODE (length1) == INTEGER_CST
|
||||
&& !integer_zerop (fold_build2 (PLUS_EXPR, bt, length2,
|
||||
convert (bt, integer_one_node))))
|
||||
unless the length of the second array is the constant zero. */
|
||||
if (TREE_CODE (length1) == INTEGER_CST && !integer_zerop (length2))
|
||||
{
|
||||
tree tem;
|
||||
bool btem;
|
||||
|
||||
tem = a1, a1 = a2, a2 = tem;
|
||||
tem = t1, t1 = t2, t2 = tem;
|
||||
tem = lb1, lb1 = lb2, lb2 = tem;
|
||||
|
@ -292,57 +291,56 @@ compare_arrays (tree result_type, tree a1, tree a2)
|
|||
a2_side_effects_p = btem;
|
||||
}
|
||||
|
||||
/* If the length of this dimension in the second array is the constant
|
||||
zero, we can just go inside the original bounds for the first
|
||||
array and see if last < first. */
|
||||
if (integer_zerop (fold_build2 (PLUS_EXPR, bt, length2,
|
||||
convert (bt, integer_one_node))))
|
||||
/* If the length of the second array is the constant zero, we can just
|
||||
use the original stored bounds for the first array and see whether
|
||||
last < first holds. */
|
||||
if (integer_zerop (length2))
|
||||
{
|
||||
tree ub = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
|
||||
tree lb = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
|
||||
length_zero_p = true;
|
||||
|
||||
comparison = build_binary_op (LT_EXPR, result_type, ub, lb);
|
||||
ub1 = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
|
||||
lb1 = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
|
||||
|
||||
comparison = build_binary_op (LT_EXPR, result_type, ub1, lb1);
|
||||
comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
|
||||
if (EXPR_P (comparison))
|
||||
SET_EXPR_LOCATION (comparison, input_location);
|
||||
|
||||
length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
|
||||
|
||||
length_zero_p = true;
|
||||
this_a1_is_null = comparison;
|
||||
this_a2_is_null = convert (result_type, boolean_true_node);
|
||||
}
|
||||
|
||||
/* If the length is some other constant value, we know that the
|
||||
this dimension in the first array cannot be superflat, so we
|
||||
can just use its length from the actual stored bounds. */
|
||||
/* Otherwise, if the length is some other constant value, we know that
|
||||
this dimension in the second array cannot be superflat, so we can
|
||||
just use its length computed from the actual stored bounds. */
|
||||
else if (TREE_CODE (length2) == INTEGER_CST)
|
||||
{
|
||||
tree bt;
|
||||
|
||||
ub1 = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
|
||||
lb1 = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
|
||||
/* Note that we know that UB2 and LB2 are constant and hence
|
||||
cannot contain a PLACEHOLDER_EXPR. */
|
||||
ub2 = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t2)));
|
||||
lb2 = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t2)));
|
||||
nbt = get_base_type (TREE_TYPE (ub1));
|
||||
bt = get_base_type (TREE_TYPE (ub1));
|
||||
|
||||
comparison
|
||||
= build_binary_op (EQ_EXPR, result_type,
|
||||
build_binary_op (MINUS_EXPR, nbt, ub1, lb1),
|
||||
build_binary_op (MINUS_EXPR, nbt, ub2, lb2));
|
||||
build_binary_op (MINUS_EXPR, bt, ub1, lb1),
|
||||
build_binary_op (MINUS_EXPR, bt, ub2, lb2));
|
||||
comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
|
||||
if (EXPR_P (comparison))
|
||||
SET_EXPR_LOCATION (comparison, input_location);
|
||||
|
||||
length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
|
||||
|
||||
this_a1_is_null = build_binary_op (LT_EXPR, result_type, ub1, lb1);
|
||||
if (EXPR_P (this_a1_is_null))
|
||||
SET_EXPR_LOCATION (this_a1_is_null, input_location);
|
||||
|
||||
this_a2_is_null = convert (result_type, boolean_false_node);
|
||||
}
|
||||
|
||||
/* Otherwise compare the computed lengths. */
|
||||
/* Otherwise, compare the computed lengths. */
|
||||
else
|
||||
{
|
||||
length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
|
||||
|
@ -353,24 +351,24 @@ compare_arrays (tree result_type, tree a1, tree a2)
|
|||
if (EXPR_P (comparison))
|
||||
SET_EXPR_LOCATION (comparison, input_location);
|
||||
|
||||
this_a1_is_null
|
||||
= build_binary_op (LT_EXPR, result_type, length1,
|
||||
convert (bt, integer_zero_node));
|
||||
this_a1_is_null = build_binary_op (EQ_EXPR, result_type, length1,
|
||||
size_zero_node);
|
||||
if (EXPR_P (this_a1_is_null))
|
||||
SET_EXPR_LOCATION (this_a1_is_null, input_location);
|
||||
|
||||
this_a2_is_null
|
||||
= build_binary_op (LT_EXPR, result_type, length2,
|
||||
convert (bt, integer_zero_node));
|
||||
this_a2_is_null = build_binary_op (EQ_EXPR, result_type, length2,
|
||||
size_zero_node);
|
||||
if (EXPR_P (this_a2_is_null))
|
||||
SET_EXPR_LOCATION (this_a2_is_null, input_location);
|
||||
}
|
||||
|
||||
/* Append expressions for this dimension to the final expressions. */
|
||||
result = build_binary_op (TRUTH_ANDIF_EXPR, result_type,
|
||||
result, comparison);
|
||||
|
||||
a1_is_null = build_binary_op (TRUTH_ORIF_EXPR, result_type,
|
||||
this_a1_is_null, a1_is_null);
|
||||
|
||||
a2_is_null = build_binary_op (TRUTH_ORIF_EXPR, result_type,
|
||||
this_a2_is_null, a2_is_null);
|
||||
|
||||
|
@ -378,7 +376,7 @@ compare_arrays (tree result_type, tree a1, tree a2)
|
|||
t2 = TREE_TYPE (t2);
|
||||
}
|
||||
|
||||
/* Unless the size of some bound is known to be zero, compare the
|
||||
/* Unless the length of some dimension is known to be zero, compare the
|
||||
data in the array. */
|
||||
if (!length_zero_p)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue