aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils2.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2019-01-27 19:14:14 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2019-01-27 19:14:14 +0000
commit683ccd0568569c67b117e87638782c6d870791b2 (patch)
treed3ad36179e7f2d6037dde651ff566d81ef28ab8a /gcc/ada/gcc-interface/utils2.c
parent33731c666114349344848ddd4218f98ef486398e (diff)
downloadgcc-683ccd0568569c67b117e87638782c6d870791b2.zip
gcc-683ccd0568569c67b117e87638782c6d870791b2.tar.gz
gcc-683ccd0568569c67b117e87638782c6d870791b2.tar.bz2
repinfo.adb (List_Component_Layout): Remove superfluous space for zero-sized field.
* repinfo.adb (List_Component_Layout): Remove superfluous space for zero-sized field. * gcc-interface/ada-tree.h (TYPE_IS_EXTRA_SUBTYPE_P): New macro. * gcc-interface/gigi.h (create_extra_subtype): Declare. * gcc-interface/decl.c (TYPE_ARRAY_SIZE_LIMIT): Likewise. (update_n_elem): New function. (gnat_to_gnu_entity): Use create_extra_subtype to create extra subtypes instead of doing it manually. <E_Array_Type>: Use update_n_elem to compute the maximum size. Use the index type instead of base type for the bounds. Set TYPE_ARRAY_MAX_SIZE of the array to the maximum size. <E_Array_Subtype>: Create an extra subtype using the index type of the base array type for self-referential bounds. Use update_n_elem to compute the maximum size. Set TYPE_ARRAY_MAX_SIZE of the array to the maximum size. (gnat_to_gnu_field): Clear DECL_NONADDRESSABLE_P on discriminants. * gcc-interface/misc.c (gnat_get_alias_set): Return the alias set of the base type for an extra subtype. (gnat_type_max_size): Remove obsolete code. * gcc-interface/trans.c (Attribute_to_gnu): Minor tweak. (can_be_lower_p): Deal with pathological types. * gcc-interface/utils.c (create_extra_subtype): New function. (create_field_decl): Minor tweak. (max_size) <tcc_reference>: Compute a better value by using the extra subtypes on the self-referential bounds. <tcc_binary>: Rewrite. Deal with "negative value" in unsigned types. <tcc_expression>: Likewise. * gcc-interface/utils2.c (compare_arrays): Retrieve the original bounds of the arrays upfront. Swap only if the second length is not constant. Use comparisons on the original bounds consistently for the null tests. (build_binary_op): Use TYPE_IS_EXTRA_SUBTYPE_P macro. (build_allocator): Minor tweak. From-SVN: r268318
Diffstat (limited to 'gcc/ada/gcc-interface/utils2.c')
-rw-r--r--gcc/ada/gcc-interface/utils2.c113
1 files changed, 51 insertions, 62 deletions
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index bb7889e..6ff1372 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -301,19 +301,31 @@ compare_arrays (location_t loc, tree result_type, tree a1, tree a2)
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 length1 = size_binop (PLUS_EXPR, size_binop (MINUS_EXPR, ub1, lb1),
+ tree dom1 = TYPE_DOMAIN (t1);
+ tree dom2 = TYPE_DOMAIN (t2);
+ tree length1 = size_binop (PLUS_EXPR,
+ size_binop (MINUS_EXPR,
+ TYPE_MAX_VALUE (dom1),
+ TYPE_MIN_VALUE (dom1)),
size_one_node);
- tree length2 = size_binop (PLUS_EXPR, size_binop (MINUS_EXPR, ub2, lb2),
+ tree length2 = size_binop (PLUS_EXPR,
+ size_binop (MINUS_EXPR,
+ TYPE_MAX_VALUE (dom2),
+ TYPE_MIN_VALUE (dom2)),
size_one_node);
+ tree ind1 = TYPE_INDEX_TYPE (dom1);
+ tree ind2 = TYPE_INDEX_TYPE (dom2);
+ tree base_type = maybe_character_type (get_base_type (ind1));
+ tree lb1 = convert (base_type, TYPE_MIN_VALUE (ind1));
+ tree ub1 = convert (base_type, TYPE_MAX_VALUE (ind1));
+ tree lb2 = convert (base_type, TYPE_MIN_VALUE (ind2));
+ tree ub2 = convert (base_type, TYPE_MAX_VALUE (ind2));
tree comparison, this_a1_is_null, this_a2_is_null;
- /* If the length of the first array is a constant, swap our operands
- unless the length of the second array is the constant zero. */
- if (TREE_CODE (length1) == INTEGER_CST && !integer_zerop (length2))
+ /* If the length of the first array is a constant and that of the second
+ array is not, swap our operands to have the constant second. */
+ if (TREE_CODE (length1) == INTEGER_CST
+ && TREE_CODE (length2) != INTEGER_CST)
{
tree tem;
bool btem;
@@ -333,17 +345,12 @@ compare_arrays (location_t loc, tree result_type, tree a1, tree a2)
last < first holds. */
if (integer_zerop (length2))
{
- tree b = get_base_type (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
-
length_zero_p = true;
- ub1
- = convert (b, TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1))));
- lb1
- = convert (b, TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1))));
+ lb1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (lb1, a1);
+ ub1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (ub1, a1);
comparison = fold_build2_loc (loc, LT_EXPR, result_type, ub1, lb1);
- comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
if (EXPR_P (comparison))
SET_EXPR_LOCATION (comparison, loc);
@@ -356,24 +363,17 @@ compare_arrays (location_t loc, tree result_type, tree a1, tree a2)
just use its length computed from the actual stored bounds. */
else if (TREE_CODE (length2) == INTEGER_CST)
{
- tree b = get_base_type (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
-
- ub1
- = convert (b, TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1))));
- lb1
- = convert (b, TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1))));
- /* Note that we know that UB2 and LB2 are constant and hence
+ /* Note that we know that LB2 and UB2 are constant and hence
cannot contain a PLACEHOLDER_EXPR. */
- ub2
- = convert (b, TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t2))));
- lb2
- = convert (b, TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t2))));
+ lb1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (lb1, a1);
+ ub1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (ub1, a1);
comparison
= fold_build2_loc (loc, EQ_EXPR, result_type,
- build_binary_op (MINUS_EXPR, b, ub1, lb1),
- build_binary_op (MINUS_EXPR, b, ub2, lb2));
- comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
+ build_binary_op (MINUS_EXPR, base_type,
+ ub1, lb1),
+ build_binary_op (MINUS_EXPR, base_type,
+ ub2, lb2));
if (EXPR_P (comparison))
SET_EXPR_LOCATION (comparison, loc);
@@ -391,26 +391,20 @@ compare_arrays (location_t loc, tree result_type, tree a1, tree a2)
comparison
= fold_build2_loc (loc, EQ_EXPR, result_type, length1, length2);
+ if (EXPR_P (comparison))
+ SET_EXPR_LOCATION (comparison, loc);
- /* If the length expression is of the form (cond ? val : 0), assume
- that cond is equivalent to (length != 0). That's guaranteed by
- construction of the array types in gnat_to_gnu_entity. */
- if (TREE_CODE (length1) == COND_EXPR
- && integer_zerop (TREE_OPERAND (length1, 2)))
- this_a1_is_null
- = invert_truthvalue_loc (loc, TREE_OPERAND (length1, 0));
- else
- this_a1_is_null = fold_build2_loc (loc, EQ_EXPR, result_type,
- length1, size_zero_node);
-
- /* Likewise for the second array. */
- if (TREE_CODE (length2) == COND_EXPR
- && integer_zerop (TREE_OPERAND (length2, 2)))
- this_a2_is_null
- = invert_truthvalue_loc (loc, TREE_OPERAND (length2, 0));
- else
- this_a2_is_null = fold_build2_loc (loc, EQ_EXPR, result_type,
- length2, size_zero_node);
+ lb1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (lb1, a1);
+ ub1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (ub1, a1);
+
+ this_a1_is_null
+ = fold_build2_loc (loc, LT_EXPR, result_type, ub1, lb1);
+
+ lb2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (lb2, a2);
+ ub2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (ub2, a2);
+
+ this_a2_is_null
+ = fold_build2_loc (loc, LT_EXPR, result_type, ub2, lb2);
}
/* Append expressions for this dimension to the final expressions. */
@@ -861,9 +855,7 @@ build_binary_op (enum tree_code op_code, tree result_type,
&& TYPE_JUSTIFIED_MODULAR_P (operation_type))
operation_type = TREE_TYPE (TYPE_FIELDS (operation_type));
- if (operation_type
- && TREE_CODE (operation_type) == INTEGER_TYPE
- && TYPE_EXTRA_SUBTYPE_P (operation_type))
+ if (operation_type && TYPE_IS_EXTRA_SUBTYPE_P (operation_type))
operation_type = get_base_type (operation_type);
modulus = (operation_type
@@ -2431,16 +2423,13 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
size = TYPE_SIZE_UNIT (TREE_TYPE (init));
/* If the size is still self-referential, reference the initializing
- expression, if it is present. If not, this must have been a
- call to allocate a library-level object, in which case we use
- the maximum size. */
- if (CONTAINS_PLACEHOLDER_P (size))
- {
- if (!ignore_init_type && init)
- size = substitute_placeholder_in_expr (size, init);
- else
- size = max_size (size, true);
- }
+ expression, if it is present. If not, this must have been a call
+ to allocate a library-level object, in which case we just use the
+ maximum size. */
+ if (!ignore_init_type && init)
+ size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, init);
+ else if (CONTAINS_PLACEHOLDER_P (size))
+ size = max_size (size, true);
/* If the size overflows, pass -1 so Storage_Error will be raised. */
if (TREE_CODE (size) == INTEGER_CST && !valid_constant_size_p (size))