aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2015-11-30 11:25:24 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2015-11-30 11:25:24 +0000
commit4ca76485c7f4588c23588204201754e00a246136 (patch)
treef39c21c5d4e4d43f3da54dd3ba8f3ce53a526182
parentc8273d2b3c03255383b0c1c39c0d985d83218419 (diff)
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231062 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ada/ChangeLog18
-rw-r--r--gcc/ada/gcc-interface/Makefile.in23
-rw-r--r--gcc/ada/gcc-interface/ada-tree.h4
-rw-r--r--gcc/ada/gcc-interface/decl.c82
-rw-r--r--gcc/ada/gcc-interface/utils.c10
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/specs/rep_clause5.ads75
7 files changed, 150 insertions, 66 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index d8196f483e4..a90fa647b5f 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -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
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index bed93b98860..3b27ae3659b 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -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 = .
diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h
index 4e368f00dad..5d93ea4bc5c 100644
--- a/gcc/ada/gcc-interface/ada-tree.h
+++ b/gcc/ada/gcc-interface/ada-tree.h
@@ -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.
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 3ae079ff904..2450b5066b0 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -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))
+ 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. */
@@ -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;
+
+ /* 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.
@@ -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.
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 0016a3fa288..f236907fc2b 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 23da95f08e8..e7a3058c4b4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gnat.dg/specs/rep_clause5.ads b/gcc/testsuite/gnat.dg/specs/rep_clause5.ads
new file mode 100644
index 00000000000..ffac17b3c29
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/rep_clause5.ads
@@ -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;