aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2009-09-26 11:25:23 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2009-09-26 11:25:23 +0000
commit03b6f8a219d3d7149ec4a69d9d75342e494a67b9 (patch)
tree67569ab9ab216cac9149ef9e9867fe4340750fc8 /gcc/ada/gcc-interface/decl.c
parent6191ca81314cf337a6f4577195b91f685f6bef3f (diff)
downloadgcc-03b6f8a219d3d7149ec4a69d9d75342e494a67b9.zip
gcc-03b6f8a219d3d7149ec4a69d9d75342e494a67b9.tar.gz
gcc-03b6f8a219d3d7149ec4a69d9d75342e494a67b9.tar.bz2
decl.c (gnat_to_gnu_entity): Filter out negative size for the array dimensions like in the constrained case.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Filter out negative size for the array dimensions like in the constrained case. <E_Array_Subtype>: Do not create an artificially non-constant high bound if the low bound is non-constant. Minor tweaks. * gcc-interface/trans.c (lvalue_required_p): Add CONSTANT parameter and turn ALIASED into a boolean parameter. Adjust calls to self. <N_Attribute_Reference>: Return 1 for more attributes. <N_Object_Renaming_Declaration>: Return 1 for non-constant objects. <N_Assignment_Statement>: Return 1 for the LHS. (Identifier_to_gnu): Adjust calls to lvalue_required_p. (call_to_gnu): Be prepared for wrapped boolean rvalues. From-SVN: r152201
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c75
1 files changed, 51 insertions, 24 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 1e54f38..12d57bc 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -1852,7 +1852,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
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;
+ tree gnu_low_field, gnu_high_field, gnu_low, gnu_high, gnu_max;
/* Make the FIELD_DECLs for the low and high bounds of this
type and then make extractions of these fields from the
@@ -1885,11 +1885,20 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
NULL_TREE);
TREE_READONLY (gnu_low) = TREE_READONLY (gnu_high) = 1;
+ /* Compute the size of this dimension. */
+ gnu_max
+ = build3 (COND_EXPR, gnu_index_base_type,
+ build2 (GE_EXPR, integer_type_node, gnu_high, gnu_low),
+ gnu_high,
+ build2 (MINUS_EXPR, gnu_index_base_type,
+ gnu_low, fold_convert (gnu_index_base_type,
+ integer_one_node)));
+
/* Make a range type with the new range in the Ada base type.
- Then make an index type with the new range in sizetype. */
+ Then make an index type with the size range in sizetype. */
gnu_index_types[index]
= create_index_type (convert (sizetype, gnu_low),
- convert (sizetype, gnu_high),
+ convert (sizetype, gnu_max),
create_range_type (gnu_index_base_type,
gnu_low, gnu_high),
gnat_entity);
@@ -2130,12 +2139,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnat_base_index = Next_Index (gnat_base_index))
{
tree gnu_index_type = get_unpadded_type (Etype (gnat_index));
- tree prec = TYPE_RM_SIZE (gnu_index_type);
- const bool wider_p
- = (compare_tree_int (prec, TYPE_PRECISION (sizetype)) > 0
- || (compare_tree_int (prec, TYPE_PRECISION (sizetype)) == 0
- && TYPE_UNSIGNED (gnu_index_type)
- != TYPE_UNSIGNED (sizetype)));
+ 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);
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);
@@ -2144,7 +2155,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= 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_high, gnu_low;
/* See if the base array type is already flat. If it is, we
are probably compiling an ACATS test but it will cause the
@@ -2160,7 +2171,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* Similarly, if one of the values overflows in sizetype and the
range is null, use 1..0 for the sizetype bounds. */
- else if (wider_p
+ else if (!subrange_p
&& TREE_CODE (gnu_min) == INTEGER_CST
&& TREE_CODE (gnu_max) == INTEGER_CST
&& (TREE_OVERFLOW (gnu_min) || TREE_OVERFLOW (gnu_max))
@@ -2174,7 +2185,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* 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 (wider_p
+ else if (!subrange_p
&& TREE_CODE (gnu_min) == INTEGER_CST
&& TREE_CODE (gnu_max) == INTEGER_CST
&& TREE_OVERFLOW (gnu_min) && TREE_OVERFLOW (gnu_max)
@@ -2200,25 +2211,41 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* Otherwise, if we can prove that the low bound minus one and
the high bound cannot overflow, we can just use the expression
- MAX (hb, lb - 1). Otherwise, we have to use the most general
- expression (hb >= lb) ? hb : lb - 1. Note that the comparison
- must be done in the original index type, to avoid any overflow
- during the conversion. */
+ MAX (hb, lb - 1). Similarly, if we can prove that the high
+ bound plus one and the low bound cannot overflow, we can use
+ the high bound as-is and MIN (hb + 1, lb) for the low bound.
+ Otherwise, we have to fall back to the most general expression
+ (hb >= lb) ? hb : lb - 1. Note that the comparison must be
+ done in the original index type, to avoid any overflow during
+ the conversion. */
else
{
gnu_high = size_binop (MINUS_EXPR, gnu_min, size_one_node);
-
- /* If gnu_high is a constant that has overflowed, the bound
- is the smallest integer so cannot be the maximum. */
- if (TREE_CODE (gnu_high) == INTEGER_CST
- && TREE_OVERFLOW (gnu_high))
+ gnu_low = size_binop (PLUS_EXPR, gnu_max, size_one_node);
+
+ /* If gnu_high is a constant that has overflowed, the low
+ bound is the smallest integer so cannot be the maximum.
+ If gnu_low is a constant that has overflowed, the high
+ bound is the highest integer so cannot be the minimum. */
+ if ((TREE_CODE (gnu_high) == INTEGER_CST
+ && TREE_OVERFLOW (gnu_high))
+ || (TREE_CODE (gnu_low) == INTEGER_CST
+ && TREE_OVERFLOW (gnu_low)))
gnu_high = gnu_max;
- /* If the index type is not wider and gnu_high is a constant
+ /* If the index type is a subrange and gnu_high a constant
that hasn't overflowed, we can use the maximum. */
- else if (!wider_p && TREE_CODE (gnu_high) == INTEGER_CST)
+ else if (subrange_p && TREE_CODE (gnu_high) == INTEGER_CST)
gnu_high = size_binop (MAX_EXPR, gnu_max, gnu_high);
+ /* If the index type is a subrange and gnu_low a constant
+ that hasn't overflowed, we can use the minimum. */
+ else if (subrange_p && TREE_CODE (gnu_low) == INTEGER_CST)
+ {
+ gnu_high = gnu_max;
+ gnu_min = size_binop (MIN_EXPR, gnu_min, gnu_low);
+ }
+
else
gnu_high
= build_cond_expr (sizetype,
@@ -2298,7 +2325,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)
- || compare_tree_int (prec, TYPE_PRECISION (sizetype)) > 0)
+ || wider_p)
need_index_type_struct = true;
}