* 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
+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
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 =
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 = .
/* 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.
? 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
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);
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))
+ else
{
- 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;
+ 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;
+ }
}
- else
- TYPE_ALIGN (gnu_type) = 0;
/* If we have a Parent_Subtype, make a field for the parent. If
this record has rep clauses, force the position to zero. */
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;
+
+ /* 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 packed;
+ 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.
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.
/* 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);
}
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);
}
}
+ /* 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);
}
+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
--- /dev/null
+-- { 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;