decl.c (gnat_to_gnu_entity): Pass correct arguments to create_field_decl.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Pass correct arguments to create_field_decl. Remove redundant iteration. Rewrite computation of the maximum size. <E_Array_Subtype>: Reorder and simplify handling of special cases. Rewrite computation of the maximum size. Use consistent naming. * gcc-interface/trans.c (Attribute_to_gnu) <Attr_Length>: Swap comparison order for consistency. Use generic integer node to build the operator and fold the result. From-SVN: r148962
This commit is contained in:
parent
b3c54c8f55
commit
4e6602a879
@ -1,3 +1,14 @@
|
||||
2009-06-26 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Pass
|
||||
correct arguments to create_field_decl. Remove redundant iteration.
|
||||
Rewrite computation of the maximum size.
|
||||
<E_Array_Subtype>: Reorder and simplify handling of special cases.
|
||||
Rewrite computation of the maximum size. Use consistent naming.
|
||||
* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Length>: Swap
|
||||
comparison order for consistency. Use generic integer node to
|
||||
build the operator and fold the result.
|
||||
|
||||
2009-06-25 Vincent Celier <celier@adacore.com>
|
||||
|
||||
* vms_data.ads: Minor comment change
|
||||
|
@ -1795,14 +1795,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
case E_String_Type:
|
||||
case E_Array_Type:
|
||||
{
|
||||
Entity_Id gnat_ind_subtype;
|
||||
Entity_Id gnat_ind_base_subtype;
|
||||
int ndim = Number_Dimensions (gnat_entity);
|
||||
int first_dim
|
||||
= (Convention (gnat_entity) == Convention_Fortran) ? ndim - 1 : 0;
|
||||
int next_dim
|
||||
= (Convention (gnat_entity) == Convention_Fortran) ? - 1 : 1;
|
||||
int index;
|
||||
Entity_Id gnat_index;
|
||||
const bool convention_fortran_p
|
||||
= (Convention (gnat_entity) == Convention_Fortran);
|
||||
const int ndim = Number_Dimensions (gnat_entity);
|
||||
tree gnu_template_fields = NULL_TREE;
|
||||
tree gnu_template_type = make_node (RECORD_TYPE);
|
||||
tree gnu_template_reference;
|
||||
@ -1812,6 +1808,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
tree *gnu_temp_fields = (tree *) alloca (ndim * sizeof (tree));
|
||||
tree gnu_max_size = size_one_node, gnu_max_size_unit;
|
||||
tree gnu_comp_size, tem;
|
||||
int index;
|
||||
|
||||
TYPE_NAME (gnu_template_type)
|
||||
= create_concat_name (gnat_entity, "XUB");
|
||||
@ -1832,10 +1829,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
tem = chainon (chainon (NULL_TREE,
|
||||
create_field_decl (get_identifier ("P_ARRAY"),
|
||||
ptr_void_type_node,
|
||||
gnu_fat_type, 0, 0, 0, 0)),
|
||||
gnu_fat_type, 0,
|
||||
NULL_TREE, NULL_TREE, 0)),
|
||||
create_field_decl (get_identifier ("P_BOUNDS"),
|
||||
gnu_ptr_template,
|
||||
gnu_fat_type, 0, 0, 0, 0));
|
||||
gnu_fat_type, 0,
|
||||
NULL_TREE, NULL_TREE, 0));
|
||||
|
||||
/* Make sure we can put this into a register. */
|
||||
TYPE_ALIGN (gnu_fat_type) = MIN (BIGGEST_ALIGNMENT, 2 * POINTER_SIZE);
|
||||
@ -1855,69 +1854,81 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
= build_unary_op (INDIRECT_REF, gnu_template_type, tem);
|
||||
TREE_READONLY (gnu_template_reference) = 1;
|
||||
|
||||
/* Now create the GCC type for each index and add the fields for
|
||||
that index to the template. */
|
||||
for (index = first_dim, gnat_ind_subtype = First_Index (gnat_entity),
|
||||
gnat_ind_base_subtype
|
||||
= First_Index (Implementation_Base_Type (gnat_entity));
|
||||
index < ndim && index >= 0;
|
||||
index += next_dim,
|
||||
gnat_ind_subtype = Next_Index (gnat_ind_subtype),
|
||||
gnat_ind_base_subtype = Next_Index (gnat_ind_base_subtype))
|
||||
/* Now create the GCC type for each index and add the fields for that
|
||||
index to the template. */
|
||||
for (index = (convention_fortran_p ? ndim - 1 : 0),
|
||||
gnat_index = First_Index (gnat_entity);
|
||||
0 <= index && index < ndim;
|
||||
index += (convention_fortran_p ? - 1 : 1),
|
||||
gnat_index = Next_Index (gnat_index))
|
||||
{
|
||||
char field_name[10];
|
||||
tree gnu_ind_subtype
|
||||
= get_unpadded_type (Base_Type (Etype (gnat_ind_subtype)));
|
||||
tree gnu_base_subtype
|
||||
= get_unpadded_type (Etype (gnat_ind_base_subtype));
|
||||
tree gnu_base_min
|
||||
= convert (sizetype, TYPE_MIN_VALUE (gnu_base_subtype));
|
||||
tree gnu_base_max
|
||||
= convert (sizetype, TYPE_MAX_VALUE (gnu_base_subtype));
|
||||
tree gnu_min_field, gnu_max_field, gnu_min, gnu_max;
|
||||
char field_name[16];
|
||||
tree gnu_index_base_type
|
||||
= get_unpadded_type (Base_Type (Etype (gnat_index)));
|
||||
tree gnu_low_field, gnu_high_field, gnu_low, gnu_high;
|
||||
|
||||
/* Make the FIELD_DECLs for the minimum and maximum of this
|
||||
type and then make extractions of that field from the
|
||||
/* Make the FIELD_DECLs for the low and high bounds of this
|
||||
type and then make extractions of these fields from the
|
||||
template. */
|
||||
sprintf (field_name, "LB%d", index);
|
||||
gnu_min_field = create_field_decl (get_identifier (field_name),
|
||||
gnu_ind_subtype,
|
||||
gnu_template_type, 0, 0, 0, 0);
|
||||
gnu_low_field = create_field_decl (get_identifier (field_name),
|
||||
gnu_index_base_type,
|
||||
gnu_template_type, 0,
|
||||
NULL_TREE, NULL_TREE, 0);
|
||||
Sloc_to_locus (Sloc (gnat_entity),
|
||||
&DECL_SOURCE_LOCATION (gnu_low_field));
|
||||
|
||||
field_name[0] = 'U';
|
||||
gnu_max_field = create_field_decl (get_identifier (field_name),
|
||||
gnu_ind_subtype,
|
||||
gnu_template_type, 0, 0, 0, 0);
|
||||
|
||||
gnu_high_field = create_field_decl (get_identifier (field_name),
|
||||
gnu_index_base_type,
|
||||
gnu_template_type, 0,
|
||||
NULL_TREE, NULL_TREE, 0);
|
||||
Sloc_to_locus (Sloc (gnat_entity),
|
||||
&DECL_SOURCE_LOCATION (gnu_min_field));
|
||||
Sloc_to_locus (Sloc (gnat_entity),
|
||||
&DECL_SOURCE_LOCATION (gnu_max_field));
|
||||
gnu_temp_fields[index] = chainon (gnu_min_field, gnu_max_field);
|
||||
&DECL_SOURCE_LOCATION (gnu_high_field));
|
||||
|
||||
/* We can't use build_component_ref here since the template
|
||||
type isn't complete yet. */
|
||||
gnu_min = build3 (COMPONENT_REF, gnu_ind_subtype,
|
||||
gnu_template_reference, gnu_min_field,
|
||||
NULL_TREE);
|
||||
gnu_max = build3 (COMPONENT_REF, gnu_ind_subtype,
|
||||
gnu_template_reference, gnu_max_field,
|
||||
NULL_TREE);
|
||||
TREE_READONLY (gnu_min) = TREE_READONLY (gnu_max) = 1;
|
||||
gnu_temp_fields[index] = chainon (gnu_low_field, gnu_high_field);
|
||||
|
||||
/* Make a range type with the new ranges, but using
|
||||
the Ada subtype. Then we convert to sizetype. */
|
||||
/* We can't use build_component_ref here since the template type
|
||||
isn't complete yet. */
|
||||
gnu_low = build3 (COMPONENT_REF, gnu_index_base_type,
|
||||
gnu_template_reference, gnu_low_field,
|
||||
NULL_TREE);
|
||||
gnu_high = build3 (COMPONENT_REF, gnu_index_base_type,
|
||||
gnu_template_reference, gnu_high_field,
|
||||
NULL_TREE);
|
||||
TREE_READONLY (gnu_low) = TREE_READONLY (gnu_high) = 1;
|
||||
|
||||
/* Make a range type with the new range in the Ada base type.
|
||||
Then make an index type with the new range in sizetype. */
|
||||
gnu_index_types[index]
|
||||
= create_index_type (convert (sizetype, gnu_min),
|
||||
convert (sizetype, gnu_max),
|
||||
create_range_type (gnu_ind_subtype,
|
||||
gnu_min, gnu_max),
|
||||
= create_index_type (convert (sizetype, gnu_low),
|
||||
convert (sizetype, gnu_high),
|
||||
create_range_type (gnu_index_base_type,
|
||||
gnu_low, gnu_high),
|
||||
gnat_entity);
|
||||
/* Update the maximum size of the array, in elements. */
|
||||
gnu_max_size
|
||||
= size_binop (MULT_EXPR, gnu_max_size,
|
||||
|
||||
/* Update the maximum size of the array in elements. */
|
||||
if (gnu_max_size)
|
||||
{
|
||||
tree gnu_index_type = get_unpadded_type (Etype (gnat_index));
|
||||
tree gnu_min
|
||||
= convert (sizetype, TYPE_MIN_VALUE (gnu_index_type));
|
||||
tree gnu_max
|
||||
= convert (sizetype, TYPE_MAX_VALUE (gnu_index_type));
|
||||
tree gnu_this_max
|
||||
= size_binop (MAX_EXPR,
|
||||
size_binop (PLUS_EXPR, size_one_node,
|
||||
size_binop (MINUS_EXPR, gnu_base_max,
|
||||
gnu_base_min)));
|
||||
size_binop (MINUS_EXPR,
|
||||
gnu_max, gnu_min)),
|
||||
size_zero_node);
|
||||
|
||||
if (TREE_CODE (gnu_this_max) == INTEGER_CST
|
||||
&& TREE_OVERFLOW (gnu_this_max))
|
||||
gnu_max_size = NULL_TREE;
|
||||
else
|
||||
gnu_max_size
|
||||
= size_binop (MULT_EXPR, gnu_max_size, gnu_this_max);
|
||||
}
|
||||
|
||||
TYPE_NAME (gnu_index_types[index])
|
||||
= create_concat_name (gnat_entity, field_name);
|
||||
@ -2006,15 +2017,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
if (Unknown_Component_Size (gnat_entity))
|
||||
Set_Component_Size (gnat_entity, annotate_value (TYPE_SIZE (tem)));
|
||||
|
||||
gnu_max_size_unit = size_binop (MAX_EXPR, size_zero_node,
|
||||
size_binop (MULT_EXPR, gnu_max_size,
|
||||
TYPE_SIZE_UNIT (tem)));
|
||||
gnu_max_size = size_binop (MAX_EXPR, bitsize_zero_node,
|
||||
size_binop (MULT_EXPR,
|
||||
convert (bitsizetype,
|
||||
gnu_max_size),
|
||||
TYPE_SIZE (tem)));
|
||||
/* Compute the maximum size of the array in units and bits. */
|
||||
if (gnu_max_size)
|
||||
{
|
||||
gnu_max_size_unit = size_binop (MULT_EXPR, gnu_max_size,
|
||||
TYPE_SIZE_UNIT (tem));
|
||||
gnu_max_size = size_binop (MULT_EXPR,
|
||||
convert (bitsizetype, gnu_max_size),
|
||||
TYPE_SIZE (tem));
|
||||
}
|
||||
else
|
||||
gnu_max_size_unit = NULL_TREE;
|
||||
|
||||
/* Now build the array type. */
|
||||
for (index = ndim - 1; index >= 0; index--)
|
||||
{
|
||||
tem = build_array_type (tem, gnu_index_types[index]);
|
||||
@ -2036,8 +2051,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
TYPE_USER_ALIGN (tem) = 1;
|
||||
}
|
||||
|
||||
TYPE_CONVENTION_FORTRAN_P (tem)
|
||||
= (Convention (gnat_entity) == Convention_Fortran);
|
||||
TYPE_CONVENTION_FORTRAN_P (tem) = convention_fortran_p;
|
||||
TREE_TYPE (TYPE_FIELDS (gnu_fat_type)) = build_pointer_type (tem);
|
||||
|
||||
/* The result type is an UNCONSTRAINED_ARRAY_TYPE that indicates the
|
||||
@ -2049,15 +2063,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
SET_TYPE_UNCONSTRAINED_ARRAY (gnu_fat_type, gnu_type);
|
||||
|
||||
/* If the maximum size doesn't overflow, use it. */
|
||||
if (TREE_CODE (gnu_max_size) == INTEGER_CST
|
||||
&& !TREE_OVERFLOW (gnu_max_size))
|
||||
TYPE_SIZE (tem)
|
||||
= size_binop (MIN_EXPR, gnu_max_size, TYPE_SIZE (tem));
|
||||
if (TREE_CODE (gnu_max_size_unit) == INTEGER_CST
|
||||
if (gnu_max_size
|
||||
&& TREE_CODE (gnu_max_size) == INTEGER_CST
|
||||
&& !TREE_OVERFLOW (gnu_max_size)
|
||||
&& TREE_CODE (gnu_max_size_unit) == INTEGER_CST
|
||||
&& !TREE_OVERFLOW (gnu_max_size_unit))
|
||||
TYPE_SIZE_UNIT (tem)
|
||||
= size_binop (MIN_EXPR, gnu_max_size_unit,
|
||||
{
|
||||
TYPE_SIZE (tem) = size_binop (MIN_EXPR, gnu_max_size,
|
||||
TYPE_SIZE (tem));
|
||||
TYPE_SIZE_UNIT (tem) = size_binop (MIN_EXPR, gnu_max_size_unit,
|
||||
TYPE_SIZE_UNIT (tem));
|
||||
}
|
||||
|
||||
create_type_decl (create_concat_name (gnat_entity, "XUA"),
|
||||
tem, NULL, !Comes_From_Source (gnat_entity),
|
||||
@ -2089,123 +2105,100 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
case E_Array_Subtype:
|
||||
|
||||
/* This is the actual data type for array variables. Multidimensional
|
||||
arrays are implemented in the gnu tree as arrays of arrays. Note
|
||||
that for the moment arrays which have sparse enumeration subtypes as
|
||||
index components create sparse arrays, which is obviously space
|
||||
inefficient but so much easier to code for now.
|
||||
arrays are implemented as arrays of arrays. Note that arrays which
|
||||
have sparse enumeration subtypes as index components create sparse
|
||||
arrays, which is obviously space inefficient but so much easier to
|
||||
code for now.
|
||||
|
||||
Also note that the subtype never refers to the unconstrained
|
||||
array type, which is somewhat at variance with Ada semantics.
|
||||
Also note that the subtype never refers to the unconstrained array
|
||||
type, which is somewhat at variance with Ada semantics.
|
||||
|
||||
First check to see if this is simply a renaming of the array
|
||||
type. If so, the result is the array type. */
|
||||
First check to see if this is simply a renaming of the array type.
|
||||
If so, the result is the array type. */
|
||||
|
||||
gnu_type = gnat_to_gnu_type (Etype (gnat_entity));
|
||||
if (!Is_Constrained (gnat_entity))
|
||||
break;
|
||||
else
|
||||
{
|
||||
Entity_Id gnat_ind_subtype;
|
||||
Entity_Id gnat_ind_base_subtype;
|
||||
int dim = Number_Dimensions (gnat_entity);
|
||||
int first_dim
|
||||
= (Convention (gnat_entity) == Convention_Fortran) ? dim - 1 : 0;
|
||||
int next_dim
|
||||
= (Convention (gnat_entity) == Convention_Fortran) ? -1 : 1;
|
||||
int index;
|
||||
Entity_Id gnat_index, gnat_base_index;
|
||||
const bool convention_fortran_p
|
||||
= (Convention (gnat_entity) == Convention_Fortran);
|
||||
const int ndim = Number_Dimensions (gnat_entity);
|
||||
tree gnu_base_type = gnu_type;
|
||||
tree *gnu_index_type = (tree *) alloca (dim * sizeof (tree));
|
||||
tree *gnu_index_types = (tree *) alloca (ndim * sizeof (tree));
|
||||
tree gnu_max_size = size_one_node, gnu_max_size_unit;
|
||||
bool need_index_type_struct = false;
|
||||
bool max_overflow = false;
|
||||
int index;
|
||||
|
||||
/* First create the gnu types for each index. Create types for
|
||||
debugging information to point to the index types if the
|
||||
are not integer types, have variable bounds, or are
|
||||
wider than sizetype. */
|
||||
|
||||
for (index = first_dim, gnat_ind_subtype = First_Index (gnat_entity),
|
||||
gnat_ind_base_subtype
|
||||
/* First create the GCC type for each index and find out whether
|
||||
special types are needed for debugging information. */
|
||||
for (index = (convention_fortran_p ? ndim - 1 : 0),
|
||||
gnat_index = First_Index (gnat_entity),
|
||||
gnat_base_index
|
||||
= First_Index (Implementation_Base_Type (gnat_entity));
|
||||
index < dim && index >= 0;
|
||||
index += next_dim,
|
||||
gnat_ind_subtype = Next_Index (gnat_ind_subtype),
|
||||
gnat_ind_base_subtype = Next_Index (gnat_ind_base_subtype))
|
||||
0 <= index && index < ndim;
|
||||
index += (convention_fortran_p ? - 1 : 1),
|
||||
gnat_index = Next_Index (gnat_index),
|
||||
gnat_base_index = Next_Index (gnat_base_index))
|
||||
{
|
||||
tree gnu_index_subtype
|
||||
= get_unpadded_type (Etype (gnat_ind_subtype));
|
||||
tree gnu_min
|
||||
= convert (sizetype, TYPE_MIN_VALUE (gnu_index_subtype));
|
||||
tree gnu_max
|
||||
= convert (sizetype, TYPE_MAX_VALUE (gnu_index_subtype));
|
||||
tree gnu_base_subtype
|
||||
= get_unpadded_type (Etype (gnat_ind_base_subtype));
|
||||
tree gnu_base_min
|
||||
= convert (sizetype, TYPE_MIN_VALUE (gnu_base_subtype));
|
||||
tree gnu_base_max
|
||||
= convert (sizetype, TYPE_MAX_VALUE (gnu_base_subtype));
|
||||
tree gnu_base_type = get_base_type (gnu_base_subtype);
|
||||
tree gnu_base_base_min
|
||||
= convert (sizetype, TYPE_MIN_VALUE (gnu_base_type));
|
||||
tree gnu_base_base_max
|
||||
= convert (sizetype, TYPE_MAX_VALUE (gnu_base_type));
|
||||
tree gnu_index_type = get_unpadded_type (Etype (gnat_index));
|
||||
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);
|
||||
tree gnu_max = convert (sizetype, gnu_orig_max);
|
||||
tree gnu_base_index_type
|
||||
= get_unpadded_type (Etype (gnat_base_index));
|
||||
tree gnu_base_orig_min = TYPE_MIN_VALUE (gnu_base_index_type);
|
||||
tree gnu_base_orig_max = TYPE_MAX_VALUE (gnu_base_index_type);
|
||||
tree gnu_high;
|
||||
tree gnu_this_max;
|
||||
|
||||
/* If the minimum and maximum values both overflow in
|
||||
SIZETYPE, but the difference in the original type
|
||||
does not overflow in SIZETYPE, ignore the overflow
|
||||
indications. */
|
||||
if ((TYPE_PRECISION (gnu_index_subtype)
|
||||
/* See if the base array type is already flat. If it is, we
|
||||
are probably compiling an ACATS test but it will cause the
|
||||
code below to malfunction if we don't handle it specially. */
|
||||
if (TREE_CODE (gnu_base_orig_min) == INTEGER_CST
|
||||
&& TREE_CODE (gnu_base_orig_max) == INTEGER_CST
|
||||
&& tree_int_cst_lt (gnu_base_orig_max, gnu_base_orig_min))
|
||||
{
|
||||
gnu_min = size_one_node;
|
||||
gnu_max = size_zero_node;
|
||||
gnu_high = gnu_max;
|
||||
}
|
||||
|
||||
/* Similarly, if one of the values overflows in sizetype and the
|
||||
range is null, use 1..0 for the sizetype bounds. */
|
||||
else if ((TYPE_PRECISION (gnu_index_type)
|
||||
> TYPE_PRECISION (sizetype)
|
||||
|| TYPE_UNSIGNED (gnu_index_subtype)
|
||||
|| TYPE_UNSIGNED (gnu_index_type)
|
||||
!= TYPE_UNSIGNED (sizetype))
|
||||
&& TREE_CODE (gnu_min) == INTEGER_CST
|
||||
&& TREE_CODE (gnu_max) == INTEGER_CST
|
||||
&& (TREE_OVERFLOW (gnu_min) || TREE_OVERFLOW (gnu_max))
|
||||
&& tree_int_cst_lt (gnu_orig_max, gnu_orig_min))
|
||||
{
|
||||
gnu_min = size_one_node;
|
||||
gnu_max = size_zero_node;
|
||||
gnu_high = gnu_max;
|
||||
}
|
||||
|
||||
/* If the minimum and maximum values both overflow in sizetype,
|
||||
but the difference in the original type does not overflow in
|
||||
sizetype, ignore the overflow indication. */
|
||||
else if ((TYPE_PRECISION (gnu_index_type)
|
||||
> TYPE_PRECISION (sizetype)
|
||||
|| TYPE_UNSIGNED (gnu_index_type)
|
||||
!= TYPE_UNSIGNED (sizetype))
|
||||
&& TREE_CODE (gnu_min) == INTEGER_CST
|
||||
&& TREE_CODE (gnu_max) == INTEGER_CST
|
||||
&& TREE_OVERFLOW (gnu_min) && TREE_OVERFLOW (gnu_max)
|
||||
&& !TREE_OVERFLOW
|
||||
(fold_build2 (MINUS_EXPR, gnu_index_subtype,
|
||||
TYPE_MAX_VALUE (gnu_index_subtype),
|
||||
TYPE_MIN_VALUE (gnu_index_subtype))))
|
||||
(convert (sizetype,
|
||||
fold_build2 (MINUS_EXPR, gnu_index_type,
|
||||
gnu_orig_max,
|
||||
gnu_orig_min))))
|
||||
{
|
||||
TREE_OVERFLOW (gnu_min) = 0;
|
||||
TREE_OVERFLOW (gnu_max) = 0;
|
||||
if (tree_int_cst_lt (gnu_max, gnu_min))
|
||||
{
|
||||
gnu_min = size_one_node;
|
||||
gnu_max = size_zero_node;
|
||||
}
|
||||
gnu_high = gnu_max;
|
||||
}
|
||||
|
||||
/* Similarly, if the range is null, use bounds of 1..0 for
|
||||
the sizetype bounds. */
|
||||
else if ((TYPE_PRECISION (gnu_index_subtype)
|
||||
> TYPE_PRECISION (sizetype)
|
||||
|| TYPE_UNSIGNED (gnu_index_subtype)
|
||||
!= TYPE_UNSIGNED (sizetype))
|
||||
&& TREE_CODE (gnu_min) == INTEGER_CST
|
||||
&& TREE_CODE (gnu_max) == INTEGER_CST
|
||||
&& (TREE_OVERFLOW (gnu_min) || TREE_OVERFLOW (gnu_max))
|
||||
&& tree_int_cst_lt (TYPE_MAX_VALUE (gnu_index_subtype),
|
||||
TYPE_MIN_VALUE (gnu_index_subtype)))
|
||||
{
|
||||
gnu_min = size_one_node;
|
||||
gnu_max = size_zero_node;
|
||||
gnu_high = gnu_max;
|
||||
}
|
||||
|
||||
/* See if the base array type is already flat. If it is, we
|
||||
are probably compiling an ACATS test, but it will cause the
|
||||
code below to malfunction if we don't handle it specially. */
|
||||
else if (TREE_CODE (gnu_base_min) == INTEGER_CST
|
||||
&& TREE_CODE (gnu_base_max) == INTEGER_CST
|
||||
&& !TREE_OVERFLOW (gnu_base_min)
|
||||
&& !TREE_OVERFLOW (gnu_base_max)
|
||||
&& tree_int_cst_lt (gnu_base_max, gnu_base_min))
|
||||
{
|
||||
gnu_min = size_one_node;
|
||||
gnu_max = size_zero_node;
|
||||
gnu_high = gnu_max;
|
||||
}
|
||||
|
||||
@ -2221,16 +2214,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
to use the expression hb >= lb ? hb : lb - 1. */
|
||||
gnu_high = size_binop (MINUS_EXPR, gnu_min, size_one_node);
|
||||
|
||||
/* If gnu_high is now an integer which overflowed, the array
|
||||
/* If gnu_high is a constant that has overflowed, the array
|
||||
cannot be superflat. */
|
||||
if (TREE_CODE (gnu_high) == INTEGER_CST
|
||||
&& TREE_OVERFLOW (gnu_high))
|
||||
gnu_high = gnu_max;
|
||||
|
||||
/* gnu_high cannot overflow if the subtype is unsigned since
|
||||
sizetype is signed, or if it is now a constant that hasn't
|
||||
/* gnu_high cannot overflow if the subtype is unsigned and
|
||||
sizetype is signed, or if it is a constant that hasn't
|
||||
overflowed. */
|
||||
else if (TYPE_UNSIGNED (gnu_base_subtype)
|
||||
else if ((TYPE_UNSIGNED (gnu_index_type)
|
||||
&& !TYPE_UNSIGNED (sizetype))
|
||||
|| TREE_CODE (gnu_high) == INTEGER_CST)
|
||||
gnu_high = size_binop (MAX_EXPR, gnu_max, gnu_high);
|
||||
|
||||
@ -2243,29 +2237,35 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
gnu_max, gnu_high);
|
||||
}
|
||||
|
||||
gnu_index_type[index]
|
||||
= create_index_type (gnu_min, gnu_high, gnu_index_subtype,
|
||||
gnu_index_types[index]
|
||||
= create_index_type (gnu_min, gnu_high, gnu_index_type,
|
||||
gnat_entity);
|
||||
|
||||
/* Also compute the maximum size of the array. Here we
|
||||
/* Update the maximum size of the array in elements. Here we
|
||||
see if any constraint on the index type of the base type
|
||||
can be used in the case of self-referential bound on
|
||||
the index type of the subtype. We look for a non-"infinite"
|
||||
can be used in the case of self-referential bound on the
|
||||
index type of the subtype. We look for a non-"infinite"
|
||||
and non-self-referential bound from any type involved and
|
||||
handle each bound separately. */
|
||||
if (gnu_max_size)
|
||||
{
|
||||
tree gnu_base_min = convert (sizetype, gnu_base_orig_min);
|
||||
tree gnu_base_max = convert (sizetype, gnu_base_orig_max);
|
||||
tree gnu_base_index_base_type
|
||||
= get_base_type (gnu_base_index_type);
|
||||
tree gnu_base_base_min
|
||||
= convert (sizetype,
|
||||
TYPE_MIN_VALUE (gnu_base_index_base_type));
|
||||
tree gnu_base_base_max
|
||||
= convert (sizetype,
|
||||
TYPE_MAX_VALUE (gnu_base_index_base_type));
|
||||
|
||||
if ((TREE_CODE (gnu_min) == INTEGER_CST
|
||||
&& !TREE_OVERFLOW (gnu_min)
|
||||
&& !operand_equal_p (gnu_min, gnu_base_base_min, 0))
|
||||
|| !CONTAINS_PLACEHOLDER_P (gnu_min)
|
||||
if (!CONTAINS_PLACEHOLDER_P (gnu_min)
|
||||
|| !(TREE_CODE (gnu_base_min) == INTEGER_CST
|
||||
&& !TREE_OVERFLOW (gnu_base_min)))
|
||||
gnu_base_min = gnu_min;
|
||||
|
||||
if ((TREE_CODE (gnu_max) == INTEGER_CST
|
||||
&& !TREE_OVERFLOW (gnu_max)
|
||||
&& !operand_equal_p (gnu_max, gnu_base_base_max, 0))
|
||||
|| !CONTAINS_PLACEHOLDER_P (gnu_max)
|
||||
if (!CONTAINS_PLACEHOLDER_P (gnu_max)
|
||||
|| !(TREE_CODE (gnu_base_max) == INTEGER_CST
|
||||
&& !TREE_OVERFLOW (gnu_base_max)))
|
||||
gnu_base_max = gnu_max;
|
||||
@ -2276,34 +2276,37 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
|| (TREE_CODE (gnu_base_max) == INTEGER_CST
|
||||
&& TREE_OVERFLOW (gnu_base_max))
|
||||
|| operand_equal_p (gnu_base_max, gnu_base_base_max, 0))
|
||||
max_overflow = true;
|
||||
|
||||
gnu_base_min = size_binop (MAX_EXPR, gnu_base_min, gnu_min);
|
||||
gnu_base_max = size_binop (MIN_EXPR, gnu_base_max, gnu_max);
|
||||
|
||||
gnu_this_max
|
||||
gnu_max_size = NULL_TREE;
|
||||
else
|
||||
{
|
||||
tree gnu_this_max
|
||||
= size_binop (MAX_EXPR,
|
||||
size_binop (PLUS_EXPR, size_one_node,
|
||||
size_binop (MINUS_EXPR, gnu_base_max,
|
||||
size_binop (MINUS_EXPR,
|
||||
gnu_base_max,
|
||||
gnu_base_min)),
|
||||
size_zero_node);
|
||||
|
||||
if (TREE_CODE (gnu_this_max) == INTEGER_CST
|
||||
&& TREE_OVERFLOW (gnu_this_max))
|
||||
max_overflow = true;
|
||||
|
||||
gnu_max_size = NULL_TREE;
|
||||
else
|
||||
gnu_max_size
|
||||
= size_binop (MULT_EXPR, gnu_max_size, gnu_this_max);
|
||||
}
|
||||
}
|
||||
|
||||
if (!integer_onep (TYPE_MIN_VALUE (gnu_index_subtype))
|
||||
|| (TREE_CODE (TYPE_MAX_VALUE (gnu_index_subtype))
|
||||
!= INTEGER_CST)
|
||||
|| TREE_CODE (gnu_index_subtype) != INTEGER_TYPE
|
||||
|| (TREE_TYPE (gnu_index_subtype)
|
||||
&& (TREE_CODE (TREE_TYPE (gnu_index_subtype))
|
||||
!= INTEGER_TYPE))
|
||||
|| TYPE_BIASED_REPRESENTATION_P (gnu_index_subtype)
|
||||
|| (TYPE_PRECISION (gnu_index_subtype)
|
||||
/* We need special types for debugging information to point to
|
||||
the index types if they have variable bounds, are not integer
|
||||
types, are biased or are wider than sizetype. */
|
||||
if (!integer_onep (gnu_orig_min)
|
||||
|| TREE_CODE (gnu_orig_max) != INTEGER_CST
|
||||
|| TREE_CODE (gnu_index_type) != INTEGER_TYPE
|
||||
|| (TREE_TYPE (gnu_index_type)
|
||||
&& TREE_CODE (TREE_TYPE (gnu_index_type))
|
||||
!= INTEGER_TYPE)
|
||||
|| TYPE_BIASED_REPRESENTATION_P (gnu_index_type)
|
||||
|| (TYPE_PRECISION (gnu_index_type)
|
||||
> TYPE_PRECISION (sizetype)))
|
||||
need_index_type_struct = true;
|
||||
}
|
||||
@ -2316,7 +2319,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
&& !Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
|
||||
{
|
||||
gnu_type = gnat_to_gnu_type (Original_Array_Type (gnat_entity));
|
||||
for (index = dim - 1; index >= 0; index--)
|
||||
for (index = ndim - 1; index >= 0; index--)
|
||||
gnu_type = TREE_TYPE (gnu_type);
|
||||
|
||||
/* One of the above calls might have caused us to be elaborated,
|
||||
@ -2409,15 +2412,22 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
| TYPE_QUAL_VOLATILE));
|
||||
}
|
||||
|
||||
/* Compute the maximum size of the array in units and bits. */
|
||||
if (gnu_max_size)
|
||||
{
|
||||
gnu_max_size_unit = size_binop (MULT_EXPR, gnu_max_size,
|
||||
TYPE_SIZE_UNIT (gnu_type));
|
||||
gnu_max_size = size_binop (MULT_EXPR,
|
||||
convert (bitsizetype, gnu_max_size),
|
||||
TYPE_SIZE (gnu_type));
|
||||
}
|
||||
else
|
||||
gnu_max_size_unit = NULL_TREE;
|
||||
|
||||
for (index = dim - 1; index >= 0; index --)
|
||||
/* Now build the array type. */
|
||||
for (index = ndim - 1; index >= 0; index --)
|
||||
{
|
||||
gnu_type = build_array_type (gnu_type, gnu_index_type[index]);
|
||||
gnu_type = build_array_type (gnu_type, gnu_index_types[index]);
|
||||
TYPE_MULTI_ARRAY_P (gnu_type) = (index > 0);
|
||||
if (array_type_has_nonaliased_component (gnat_entity, gnu_type))
|
||||
TYPE_NONALIASED_COMPONENT (gnu_type) = 1;
|
||||
@ -2427,10 +2437,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
TYPE_STUB_DECL (gnu_type)
|
||||
= create_type_stub_decl (gnu_entity_name, gnu_type);
|
||||
|
||||
/* If we are at file level and this is a multi-dimensional array, we
|
||||
need to make a variable corresponding to the stride of the
|
||||
/* If we are at file level and this is a multi-dimensional array,
|
||||
we need to make a variable corresponding to the stride of the
|
||||
inner dimensions. */
|
||||
if (global_bindings_p () && dim > 1)
|
||||
if (global_bindings_p () && ndim > 1)
|
||||
{
|
||||
tree gnu_str_name = get_identifier ("ST");
|
||||
tree gnu_arr_type;
|
||||
@ -2483,9 +2493,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
TYPE_NAME (gnu_bound_rec)
|
||||
= create_concat_name (gnat_entity, "XA");
|
||||
|
||||
for (index = dim - 1; index >= 0; index--)
|
||||
for (index = ndim - 1; index >= 0; index--)
|
||||
{
|
||||
tree gnu_index = TYPE_INDEX_TYPE (gnu_index_type[index]);
|
||||
tree gnu_index = TYPE_INDEX_TYPE (gnu_index_types[index]);
|
||||
tree gnu_index_name = TYPE_NAME (gnu_index);
|
||||
|
||||
if (TREE_CODE (gnu_index_name) == TYPE_DECL)
|
||||
@ -2513,20 +2523,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
gnat_to_gnu_type
|
||||
(Original_Array_Type (gnat_entity)));
|
||||
|
||||
TYPE_CONVENTION_FORTRAN_P (gnu_type)
|
||||
= (Convention (gnat_entity) == Convention_Fortran);
|
||||
TYPE_CONVENTION_FORTRAN_P (gnu_type) = convention_fortran_p;
|
||||
TYPE_PACKED_ARRAY_TYPE_P (gnu_type)
|
||||
= (Is_Packed_Array_Type (gnat_entity)
|
||||
&& Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)));
|
||||
|
||||
/* If our size depends on a placeholder and the maximum size doesn't
|
||||
/* If the size is self-referential and the maximum size doesn't
|
||||
overflow, use it. */
|
||||
if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type))
|
||||
&& gnu_max_size
|
||||
&& !(TREE_CODE (gnu_max_size) == INTEGER_CST
|
||||
&& TREE_OVERFLOW (gnu_max_size))
|
||||
&& !(TREE_CODE (gnu_max_size_unit) == INTEGER_CST
|
||||
&& TREE_OVERFLOW (gnu_max_size_unit))
|
||||
&& !max_overflow)
|
||||
&& TREE_OVERFLOW (gnu_max_size_unit)))
|
||||
{
|
||||
TYPE_SIZE (gnu_type) = size_binop (MIN_EXPR, gnu_max_size,
|
||||
TYPE_SIZE (gnu_type));
|
||||
|
@ -1552,43 +1552,38 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
|
||||
/* We used to compute the length as max (hb - lb + 1, 0),
|
||||
which could overflow for some cases of empty arrays, e.g.
|
||||
when lb == index_type'first. We now compute the length as
|
||||
(hb < lb) ? 0 : hb - lb + 1, which would only overflow in
|
||||
(hb >= lb) ? hb - lb + 1 : 0, which would only overflow in
|
||||
much rarer cases, for extremely large arrays we expect
|
||||
never to encounter in practice. In addition, the former
|
||||
computation required the use of potentially constraining
|
||||
signed arithmetic while the latter doesn't. Note that the
|
||||
comparison must be done in the original index base type,
|
||||
otherwise the conversion of either bound to gnu_compute_type
|
||||
may overflow. */
|
||||
|
||||
tree gnu_compute_type = get_base_type (gnu_result_type);
|
||||
|
||||
tree index_type
|
||||
= TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type));
|
||||
tree lb
|
||||
= convert (gnu_compute_type, TYPE_MIN_VALUE (index_type));
|
||||
tree hb
|
||||
= convert (gnu_compute_type, TYPE_MAX_VALUE (index_type));
|
||||
|
||||
signed arithmetic while the latter doesn't. Note that
|
||||
the comparison must be done in the original index type,
|
||||
to avoid any overflow during the conversion. */
|
||||
tree comp_type = get_base_type (gnu_result_type);
|
||||
tree index_type = TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type));
|
||||
tree lb = TYPE_MIN_VALUE (index_type);
|
||||
tree hb = TYPE_MAX_VALUE (index_type);
|
||||
gnu_result
|
||||
= build3
|
||||
(COND_EXPR, gnu_compute_type,
|
||||
build_binary_op (LT_EXPR, get_base_type (index_type),
|
||||
TYPE_MAX_VALUE (index_type),
|
||||
TYPE_MIN_VALUE (index_type)),
|
||||
convert (gnu_compute_type, integer_zero_node),
|
||||
build_binary_op
|
||||
(PLUS_EXPR, gnu_compute_type,
|
||||
build_binary_op (MINUS_EXPR, gnu_compute_type, hb, lb),
|
||||
convert (gnu_compute_type, integer_one_node)));
|
||||
= build_binary_op (PLUS_EXPR, comp_type,
|
||||
build_binary_op (MINUS_EXPR,
|
||||
comp_type,
|
||||
convert (comp_type, hb),
|
||||
convert (comp_type, lb)),
|
||||
convert (comp_type, integer_one_node));
|
||||
gnu_result
|
||||
= build_cond_expr (comp_type,
|
||||
build_binary_op (GE_EXPR,
|
||||
integer_type_node,
|
||||
hb, lb),
|
||||
gnu_result,
|
||||
convert (comp_type, integer_zero_node));
|
||||
}
|
||||
}
|
||||
|
||||
/* If this has a PLACEHOLDER_EXPR, qualify it by the object we are
|
||||
handling. Note that these attributes could not have been used on
|
||||
an unconstrained array type. */
|
||||
gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result,
|
||||
gnu_prefix);
|
||||
gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result, gnu_prefix);
|
||||
|
||||
/* Cache the expression we have just computed. Since we want to do it
|
||||
at runtime, we force the use of a SAVE_EXPR and let the gimplifier
|
||||
|
Loading…
Reference in New Issue
Block a user