ada-tree.h (TYPE_MAX_ALIGN): New macro.

* gcc-interface/ada-tree.h (TYPE_MAX_ALIGN): New macro.
	* gcc-interface/decl.c (gnat_to_gnu_entity): Do not set PACKED to -2.
	Remove obsolete code setting the alignment on some atomic types.
	When the type has no alignment but needs strict alignment and has a
	size clause, compute a maximum alignment and set it on the type.
	(adjust_packed): Remove handling of -2 argument.  Deal with TYPE_ALIGN
	and TYPE_MAX_ALIGN directly.
	(gnat_to_gnu_field): Do not document -2 as argument.
	(components_to_record): Likewise.
	* gcc-interface/utils.c (finish_record_type): Do not bump alignment of
	the record type beyond TYPE_MAX_ALIGN.  Reset the latter on exit.

	* gcc-interface/Makefile.in (PICFLAG_FOR_TARGET): Move around.
	(GNATLIBCFLAGS_FOR_C): Reformat.
	(GCC_CFLAGS): Delete.

From-SVN: r231062
This commit is contained in:
Eric Botcazou 2015-11-30 11:25:24 +00:00 committed by Eric Botcazou
parent 6501d5fea0
commit 14ecca2eea
7 changed files with 151 additions and 67 deletions

View file

@ -1,3 +1,21 @@
2015-11-30 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/ada-tree.h (TYPE_MAX_ALIGN): New macro.
* gcc-interface/decl.c (gnat_to_gnu_entity): Do not set PACKED to -2.
Remove obsolete code setting the alignment on some atomic types.
When the type has no alignment but needs strict alignment and has a
size clause, compute a maximum alignment and set it on the type.
(adjust_packed): Remove handling of -2 argument. Deal with TYPE_ALIGN
and TYPE_MAX_ALIGN directly.
(gnat_to_gnu_field): Do not document -2 as argument.
(components_to_record): Likewise.
* gcc-interface/utils.c (finish_record_type): Do not bump alignment of
the record type beyond TYPE_MAX_ALIGN. Reset the latter on exit.
* gcc-interface/Makefile.in (PICFLAG_FOR_TARGET): Move around.
(GNATLIBCFLAGS_FOR_C): Reformat.
(GCC_CFLAGS): Delete.
2015-11-29 Matthias Klose <doko@ubuntu.com>
PR ada/68564

View file

@ -111,13 +111,12 @@ NO_SIBLING_ADAFLAGS = -fno-optimize-sibling-calls
NO_REORDER_ADAFLAGS = -fno-toplevel-reorder
GNATLIBFLAGS = -W -Wall -gnatpg -nostdinc
GNATLIBCFLAGS = -g -O2
PICFLAG_FOR_TARGET = @PICFLAG_FOR_TARGET@
# Pretend that _Unwind_GetIPInfo is available for the target by default. This
# should be autodetected during the configuration of libada and passed down to
# here, but we need something for --disable-libada and hope for the best.
GNATLIBCFLAGS_FOR_C = -W -Wall $(GNATLIBCFLAGS) \
-fexceptions -DIN_RTS -DHAVE_GETIPINFO
GNATLIBCFLAGS_FOR_C = \
-W -Wall $(GNATLIBCFLAGS) -fexceptions -DIN_RTS -DHAVE_GETIPINFO
PICFLAG_FOR_TARGET = @PICFLAG_FOR_TARGET@
ALL_ADAFLAGS = $(CFLAGS) $(ADA_CFLAGS) $(ADAFLAGS)
THREAD_KIND = native
THREADSLIB =
@ -132,22 +131,6 @@ soext = .so
shext =
hyphen = -
# Define this as & to perform parallel make on a Sequent.
# Note that this has some bugs, and it seems currently necessary
# to compile all the gen* files first by hand to avoid erroneous results.
P =
# This is used instead of ALL_CFLAGS when compiling with GCC_FOR_TARGET.
# It specifies -B./.
# It also specifies -B$(tooldir)/ to find as and ld for a cross compiler.
GCC_CFLAGS = $(INTERNAL_CFLAGS) $(T_CFLAGS) $(CFLAGS)
# Tools to use when building a cross-compiler.
# These are used because `configure' appends `cross-make'
# to the makefile when making a cross-compiler.
# We don't use cross-make. Instead we use the tools from the build tree,
# if they are available.
# program_transform_name and objdir are set by configure.ac.
program_transform_name =
objdir = .

View file

@ -176,6 +176,10 @@ do { \
/* True if TYPE can alias any other types. */
#define TYPE_UNIVERSAL_ALIASING_P(NODE) TYPE_LANG_FLAG_6 (NODE)
/* For RECORD_TYPE, UNION_TYPE, and QUAL_UNION_TYPE, this holds the maximum
alignment value the type ought to have. */
#define TYPE_MAX_ALIGN(NODE) (TYPE_PRECISION (RECORD_OR_UNION_CHECK (NODE)))
/* For an UNCONSTRAINED_ARRAY_TYPE, this is the record containing both the
template and the object.

View file

@ -2829,11 +2829,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
? 1
: Component_Alignment (gnat_entity) == Calign_Storage_Unit
? -1
: (Known_Alignment (gnat_entity)
|| (Strict_Alignment (gnat_entity)
&& Known_RM_Size (gnat_entity)))
? -2
: 0;
: 0;
const bool has_align = Known_Alignment (gnat_entity);
const bool has_discr = Has_Discriminants (gnat_entity);
const bool has_rep = Has_Specified_Layout (gnat_entity);
const bool is_extension
@ -2872,7 +2869,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
suppress expanding incomplete types. */
gnu_type = make_node (tree_code_for_record_type (gnat_entity));
TYPE_NAME (gnu_type) = gnu_entity_name;
TYPE_PACKED (gnu_type) = (packed != 0) || has_rep;
TYPE_PACKED (gnu_type) = (packed != 0) || has_align || has_rep;
TYPE_REVERSE_STORAGE_ORDER (gnu_type)
= Reverse_Storage_Order (gnat_entity);
process_attributes (&gnu_type, &attr_list, true, gnat_entity);
@ -2883,38 +2880,32 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
this_deferred = true;
}
/* If both a size and rep clause was specified, put the size in
the record type now so that it can get the proper mode. */
/* If both a size and rep clause were specified, put the size on
the record type now so that it can get the proper layout. */
if (has_rep && Known_RM_Size (gnat_entity))
TYPE_SIZE (gnu_type)
= UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
/* Always set the alignment here so that it can be used to
set the mode, if it is making the alignment stricter. If
it is invalid, it will be checked again below. If this is to
be Atomic, choose a default alignment of a word unless we know
the size and it's smaller. */
if (Known_Alignment (gnat_entity))
/* Always set the alignment on the record type here so that it can
get the proper layout. */
if (has_align)
TYPE_ALIGN (gnu_type)
= validate_alignment (Alignment (gnat_entity), gnat_entity, 0);
else if (Is_Atomic_Or_VFA (gnat_entity) && Known_Esize (gnat_entity))
{
unsigned int size = UI_To_Int (Esize (gnat_entity));
TYPE_ALIGN (gnu_type)
= size >= BITS_PER_WORD ? BITS_PER_WORD : ceil_pow2 (size);
}
/* If a type needs strict alignment, the minimum size will be the
type size instead of the RM size (see validate_size). Cap the
alignment, lest it causes this type size to become too large. */
else if (Strict_Alignment (gnat_entity) && Known_RM_Size (gnat_entity))
{
unsigned int raw_size = UI_To_Int (RM_Size (gnat_entity));
unsigned int raw_align = raw_size & -raw_size;
if (raw_align < BIGGEST_ALIGNMENT)
TYPE_ALIGN (gnu_type) = raw_align;
}
else
TYPE_ALIGN (gnu_type) = 0;
{
TYPE_ALIGN (gnu_type) = 0;
/* If a type needs strict alignment, the minimum size will be the
type size instead of the RM size (see validate_size). Cap the
alignment lest it causes this type size to become too large. */
if (Strict_Alignment (gnat_entity) && Known_RM_Size (gnat_entity))
{
unsigned int max_size = UI_To_Int (RM_Size (gnat_entity));
unsigned int max_align = max_size & -max_size;
if (max_align < BIGGEST_ALIGNMENT)
TYPE_MAX_ALIGN (gnu_type) = max_align;
}
}
/* If we have a Parent_Subtype, make a field for the parent. If
this record has rep clauses, force the position to zero. */
@ -6502,25 +6493,29 @@ adjust_packed (tree field_type, tree record_type, int packed)
if (type_has_variable_size (field_type))
return 0;
/* In the other cases, we can honor the packing. */
if (packed)
return packed;
/* If the alignment of the record is specified and the field type
is over-aligned, request Storage_Unit alignment for the field. */
if (packed == -2)
{
if (TYPE_ALIGN (field_type) > TYPE_ALIGN (record_type))
return -1;
else
return 0;
}
if (TYPE_ALIGN (record_type)
&& TYPE_ALIGN (field_type) > TYPE_ALIGN (record_type))
return -1;
return packed;
/* Likewise if the maximum alignment of the record is specified. */
if (TYPE_MAX_ALIGN (record_type)
&& TYPE_ALIGN (field_type) > TYPE_MAX_ALIGN (record_type))
return -1;
return 0;
}
/* Return a GCC tree for a field corresponding to GNAT_FIELD to be
placed in GNU_RECORD_TYPE.
PACKED is 1 if the enclosing record is packed, -1 if the enclosing
record has Component_Alignment of Storage_Unit, -2 if the enclosing
record has a specified alignment.
PACKED is 1 if the enclosing record is packed or -1 if the enclosing
record has Component_Alignment of Storage_Unit.
DEFINITION is true if this field is for a record being defined.
@ -6989,9 +6984,8 @@ typedef struct vinfo
GNU_FIELD_LIST. The other calls to this function are recursive calls for
the component list of a variant and, in this case, GNU_FIELD_LIST is empty.
PACKED is 1 if this is for a packed record, -1 if this is for a record
with Component_Alignment of Storage_Unit, -2 if this is for a record
with a specified alignment.
PACKED is 1 if this is for a packed record or -1 if this is for a record
with Component_Alignment of Storage_Unit.
DEFINITION is true if we are defining this record type.

View file

@ -1694,7 +1694,8 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
/* The enclosing record type must be sufficiently aligned.
Otherwise, if no alignment was specified for it and it
has been laid out already, bump its alignment to the
desired one if this is compatible with its size. */
desired one if this is compatible with its size and
maximum alignment, if any. */
if (TYPE_ALIGN (record_type) >= align)
{
DECL_ALIGN (field) = MAX (DECL_ALIGN (field), align);
@ -1702,7 +1703,9 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
}
else if (!had_align
&& rep_level == 0
&& value_factor_p (TYPE_SIZE (record_type), align))
&& value_factor_p (TYPE_SIZE (record_type), align)
&& (!TYPE_MAX_ALIGN (record_type)
|| TYPE_MAX_ALIGN (record_type) >= align))
{
TYPE_ALIGN (record_type) = align;
DECL_ALIGN (field) = MAX (DECL_ALIGN (field), align);
@ -1800,6 +1803,9 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
}
}
/* Reset the TYPE_MAX_ALIGN field since it's private to gigi. */
TYPE_MAX_ALIGN (record_type) = 0;
if (debug_info_p)
rest_of_record_type_compilation (record_type);
}

View file

@ -1,3 +1,7 @@
2015-11-30 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/rep_clause5.ads: New test.
2015-11-29 Jan Hubicka <hubicka@ucw.cz>
PR c/67106

View file

@ -0,0 +1,75 @@
-- { dg-do compile }
pragma Implicit_Packing;
package Rep_Clause5 is
type Modes_Type is (Mode_0, Mode_1);
for Modes_Type'size use 8;
type Mode_Record_Type is
record
Mode_1 : aliased Modes_Type;
Mode_2 : aliased Modes_Type;
Mode_3 : aliased Modes_Type;
Mode_4 : aliased Modes_Type;
Time : aliased Float;
end record;
for Mode_Record_Type use
record
Mode_1 at 00 range 00 .. 07;
Mode_2 at 01 range 00 .. 07;
Mode_3 at 02 range 00 .. 07;
Mode_4 at 03 range 00 .. 07;
Time at 04 range 00 .. 31;
end record;
for Mode_Record_Type'Size use 64;
for Mode_Record_Type'Alignment use 4;
type Array_1_Type is array (0 .. 31) of Boolean;
for Array_1_Type'size use 32;
type Array_2_Type is array (0 .. 127) of Boolean;
for Array_2_Type'size use 128;
type Array_3_Type is array (0 .. 31) of Boolean;
for Array_3_Type'size use 32;
type Unsigned_Long is mod 2 ** 32;
type Array_4_Type is array (1 .. 6) of unsigned_Long;
type Primary_Data_Type is
record
Array_1 : aliased Array_1_Type;
Mode_Record : aliased Mode_Record_Type;
Array_2 : aliased Array_2_Type;
Array_3 : Array_3_Type;
Array_4 : Array_4_Type;
end record;
for Primary_Data_Type use
record
Array_1 at 0 range 0 .. 31; -- WORD 1
Mode_Record at 4 range 0 .. 63; -- WORD 2 .. 3
Array_2 at 12 range 0 .. 127; -- WORD 4 .. 7
Array_3 at 28 range 0 .. 31; -- WORD 8
Array_4 at 32 range 0 .. 191; -- WORD 9 .. 14
end record;
for Primary_Data_Type'Size use 448;
type Results_Record_Type is
record
Thirty_Two_Bit_Pad : Float;
Result : Primary_Data_Type;
end record;
for Results_Record_Type use
record
Thirty_Two_Bit_Pad at 0 range 0 .. 31;
Result at 4 range 0 .. 447;
end record;
end Rep_Clause5;