diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2010-04-17 08:14:08 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2010-04-17 08:14:08 +0000 |
commit | 1081f5a7c753c0850becc3758adee1ce3f968ec9 (patch) | |
tree | f52b778a479d5827dea31191f94c7e6e2e92abf9 /gcc/ada/gcc-interface/decl.c | |
parent | 80d56d040e2050cf478e7e0703d5fe9af30eaac1 (diff) | |
download | gcc-1081f5a7c753c0850becc3758adee1ce3f968ec9.zip gcc-1081f5a7c753c0850becc3758adee1ce3f968ec9.tar.gz gcc-1081f5a7c753c0850becc3758adee1ce3f968ec9.tar.bz2 |
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
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 72 |
1 files changed, 28 insertions, 44 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 02d7296..b7fd331 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -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); |