Commit 6e0f0975 by Eric Botcazou Committed by Eric Botcazou

decl.c (gnat_to_gnu_entity): Rewrite Esize calculation.

	* gcc-interface/decl.c (gnat_to_gnu_entity): Rewrite Esize calculation.
	<E_Signed_Integer_Subtype>: Set the RM size on the integer type
	before wrapping it up in the record type.  Do not overwrite the
	Ada size of the record type with the Esize.

From-SVN: r146452
parent bbbbb16a
2009-04-20 Eric Botcazou <ebotcazou@adacore.com> 2009-04-20 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity): Rewrite Esize calculation.
<E_Signed_Integer_Subtype>: Set the RM size on the integer type
before wrapping it up in the record type. Do not overwrite the
Ada size of the record type with the Esize.
2009-04-20 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (unchecked_conversion_lhs_nop): New predicate. * gcc-interface/trans.c (unchecked_conversion_lhs_nop): New predicate.
(gnat_to_gnu) <N_Unchecked_Type_Conversion>: Return the expression (gnat_to_gnu) <N_Unchecked_Type_Conversion>: Return the expression
if the conversion is on the LHS of an assignment and a no-op. if the conversion is on the LHS of an assignment and a no-op.
...@@ -201,18 +201,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -201,18 +201,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* True if this entity is to be considered as imported. */ /* True if this entity is to be considered as imported. */
bool imported_p = (Is_Imported (gnat_entity) bool imported_p = (Is_Imported (gnat_entity)
&& No (Address_Clause (gnat_entity))); && No (Address_Clause (gnat_entity)));
unsigned int esize unsigned int esize, align = 0;
= ((Known_Esize (gnat_entity)
&& UI_Is_In_Int_Range (Esize (gnat_entity)))
? MIN (UI_To_Int (Esize (gnat_entity)),
IN (kind, Float_Kind)
? fp_prec_to_size (LONG_DOUBLE_TYPE_SIZE)
: IN (kind, Access_Kind) ? POINTER_SIZE * 2
: LONG_LONG_TYPE_SIZE)
: LONG_LONG_TYPE_SIZE);
unsigned int align = 0;
struct attrib *attr_list = NULL; struct attrib *attr_list = NULL;
/* First compute a default value for the size of the entity. */
if (Known_Esize (gnat_entity) && UI_Is_In_Int_Range (Esize (gnat_entity)))
{
unsigned int max_esize;
esize = UI_To_Int (Esize (gnat_entity));
if (IN (kind, Float_Kind))
max_esize = fp_prec_to_size (LONG_DOUBLE_TYPE_SIZE);
else if (IN (kind, Access_Kind))
max_esize = POINTER_SIZE * 2;
else
max_esize = LONG_LONG_TYPE_SIZE;
esize = MIN (esize, max_esize);
}
else
esize = LONG_LONG_TYPE_SIZE;
/* Since a use of an Itype is a definition, process it as such if it /* Since a use of an Itype is a definition, process it as such if it
is not in a with'ed unit. */ is not in a with'ed unit. */
if (!definition if (!definition
...@@ -1561,10 +1570,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -1561,10 +1570,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
subtypes of Standard.Boolean. */ subtypes of Standard.Boolean. */
if (Is_Packed_Array_Type (gnat_entity) if (Is_Packed_Array_Type (gnat_entity)
&& Is_Bit_Packed_Array (Original_Array_Type (gnat_entity))) && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
{
esize = UI_To_Int (RM_Size (gnat_entity)); esize = UI_To_Int (RM_Size (gnat_entity));
TYPE_PACKED_ARRAY_TYPE_P (gnu_type) = 1;
}
else if (TREE_CODE (TREE_TYPE (gnu_type)) == BOOLEAN_TYPE) else if (TREE_CODE (TREE_TYPE (gnu_type)) == BOOLEAN_TYPE)
esize = 1; esize = 1;
...@@ -1612,26 +1618,29 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -1612,26 +1618,29 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
within a subtype hierarchy. */ within a subtype hierarchy. */
relate_alias_sets (gnu_type, TREE_TYPE (gnu_type), ALIAS_SET_COPY); relate_alias_sets (gnu_type, TREE_TYPE (gnu_type), ALIAS_SET_COPY);
/* If the type we are dealing with is to represent a packed array, /* If the type we are dealing with represents a bit-packed array,
we need to have the bits left justified on big-endian targets we need to have the bits left justified on big-endian targets
and right justified on little-endian targets. We also need to and right justified on little-endian targets. We also need to
ensure that when the value is read (e.g. for comparison of two ensure that when the value is read (e.g. for comparison of two
such values), we only get the good bits, since the unused bits such values), we only get the good bits, since the unused bits
are uninitialized. Both goals are accomplished by wrapping the are uninitialized. Both goals are accomplished by wrapping up
modular value in an enclosing struct. */ the modular type in an enclosing record type. */
if (Is_Packed_Array_Type (gnat_entity) if (Is_Packed_Array_Type (gnat_entity)
&& Is_Bit_Packed_Array (Original_Array_Type (gnat_entity))) && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
{ {
tree gnu_field_type = gnu_type; tree gnu_field_type, gnu_field;
tree gnu_field;
TYPE_RM_SIZE_NUM (gnu_field_type) /* Set the RM size before wrapping up the type. */
TYPE_RM_SIZE_NUM (gnu_type)
= UI_To_gnu (RM_Size (gnat_entity), bitsizetype); = UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
TYPE_PACKED_ARRAY_TYPE_P (gnu_type) = 1;
gnu_field_type = gnu_type;
gnu_type = make_node (RECORD_TYPE); gnu_type = make_node (RECORD_TYPE);
TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "JM"); TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "JM");
/* Propagate the alignment of the modular type to the record. /* Propagate the alignment of the modular type to the record.
This means that bitpacked arrays have "ceil" alignment for This means that bit-packed arrays have "ceil" alignment for
their size, which may seem counter-intuitive but makes it their size, which may seem counter-intuitive but makes it
possible to easily overlay them on modular types. */ possible to easily overlay them on modular types. */
TYPE_ALIGN (gnu_type) = TYPE_ALIGN (gnu_field_type); TYPE_ALIGN (gnu_type) = TYPE_ALIGN (gnu_field_type);
...@@ -1650,7 +1659,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -1650,7 +1659,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
finish_record_type (gnu_type, gnu_field, 0, false); finish_record_type (gnu_type, gnu_field, 0, false);
TYPE_JUSTIFIED_MODULAR_P (gnu_type) = 1; TYPE_JUSTIFIED_MODULAR_P (gnu_type) = 1;
SET_TYPE_ADA_SIZE (gnu_type, bitsize_int (esize));
relate_alias_sets (gnu_type, gnu_field_type, ALIAS_SET_COPY); relate_alias_sets (gnu_type, gnu_field_type, ALIAS_SET_COPY);
} }
...@@ -1663,8 +1671,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -1663,8 +1671,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
&& (align = UI_To_Int (Alignment (gnat_entity)) * BITS_PER_UNIT) && (align = UI_To_Int (Alignment (gnat_entity)) * BITS_PER_UNIT)
&& align < TYPE_ALIGN (gnu_type)) && align < TYPE_ALIGN (gnu_type))
{ {
tree gnu_field_type = gnu_type; tree gnu_field_type, gnu_field;
tree gnu_field;
/* Set the RM size before wrapping up the type. */
TYPE_RM_SIZE_NUM (gnu_type)
= UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
gnu_field_type = gnu_type;
gnu_type = make_node (RECORD_TYPE); gnu_type = make_node (RECORD_TYPE);
TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "PAD"); TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "PAD");
...@@ -1685,7 +1697,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -1685,7 +1697,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
finish_record_type (gnu_type, gnu_field, 0, false); finish_record_type (gnu_type, gnu_field, 0, false);
TYPE_IS_PADDING_P (gnu_type) = 1; TYPE_IS_PADDING_P (gnu_type) = 1;
SET_TYPE_ADA_SIZE (gnu_type, bitsize_int (esize));
relate_alias_sets (gnu_type, gnu_field_type, ALIAS_SET_COPY); relate_alias_sets (gnu_type, gnu_field_type, ALIAS_SET_COPY);
} }
......
2009-04-20 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/small_alignment.ads: New test.
2009-04-20 Ian Lance Taylor <iant@google.com> 2009-04-20 Ian Lance Taylor <iant@google.com>
* gcc.dg/Wcxx-compat-3.c: New testcase. * gcc.dg/Wcxx-compat-3.c: New testcase.
......
-- { dg-compile }
package Small_Alignment is
type Int is range -512 .. 511;
for Int'Alignment use 1;
type R is record
I: Int;
end record;
Pragma Pack (R);
end Small_Alignment;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment