ada-tree.h (TYPE_MAX_ALIGN): New macro.
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 30 Nov 2015 11:25:24 +0000 (11:25 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 30 Nov 2015 11:25:24 +0000 (11:25 +0000)
* 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

gcc/ada/ChangeLog
gcc/ada/gcc-interface/Makefile.in
gcc/ada/gcc-interface/ada-tree.h
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/utils.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/specs/rep_clause5.ads [new file with mode: 0644]

index d8196f483e4aa38c2fcf534bef73bf86473f8320..a90fa647b5f7c94019eb7480d1a248b05e5ed739 100644 (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
index bed93b988603157f075bc4e7e180fbb12045d804..3b27ae3659b6cadde6afdd2bedc6f0859bc6d099 100644 (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 = .
index 4e368f00dad90e49fd4f605558b77a972a34510c..5d93ea4bc5cb70ea1e79c6830ecdd175491c2e06 100644 (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.
 
index 3ae079ff9047f217ac52955a4fbde522735f0f6b..2450b5066b05759a8fcdd138b254c75ae6f610e2 100644 (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))
+       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.
 
index 0016a3fa288fafd480f5ac4e18eab7c0244b734d..f236907fc2b2f672271064685af56b78c48dc2ba 100644 (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);
 }
index 23da95f08e86125a7728ad33b8090c29af1bd4db..e7a3058c4b4e4252cf4ed392736aa307fd8243e1 100644 (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
diff --git a/gcc/testsuite/gnat.dg/specs/rep_clause5.ads b/gcc/testsuite/gnat.dg/specs/rep_clause5.ads
new file mode 100644 (file)
index 0000000..ffac17b
--- /dev/null
@@ -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;