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:
parent
6501d5fea0
commit
14ecca2eea
7 changed files with 151 additions and 67 deletions
|
@ -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
|
||||
|
|
|
@ -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 = .
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
75
gcc/testsuite/gnat.dg/specs/rep_clause5.ads
Normal file
75
gcc/testsuite/gnat.dg/specs/rep_clause5.ads
Normal 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;
|
Loading…
Add table
Reference in a new issue