diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2009-09-26 11:25:23 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2009-09-26 11:25:23 +0000 |
commit | 03b6f8a219d3d7149ec4a69d9d75342e494a67b9 (patch) | |
tree | 67569ab9ab216cac9149ef9e9867fe4340750fc8 /gcc/ada/gcc-interface/decl.c | |
parent | 6191ca81314cf337a6f4577195b91f685f6bef3f (diff) | |
download | gcc-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.c | 75 |
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; } |