diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2015-11-30 11:25:24 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2015-11-30 11:25:24 +0000 |
commit | 14ecca2eea820447afe3214ed635883fbc4244a4 (patch) | |
tree | f39c21c5d4e4d43f3da54dd3ba8f3ce53a526182 /gcc | |
parent | 6501d5fea036e5d7c4f5f8037f217b6e8d07a60d (diff) | |
download | gcc-14ecca2eea820447afe3214ed635883fbc4244a4.zip gcc-14ecca2eea820447afe3214ed635883fbc4244a4.tar.gz gcc-14ecca2eea820447afe3214ed635883fbc4244a4.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ada/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/Makefile.in | 23 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/ada-tree.h | 4 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 82 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/specs/rep_clause5.ads | 75 |
7 files changed, 150 insertions, 66 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index d8196f4..a90fa64 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 bed93b9..3b27ae3 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 4e368f0..5d93ea4 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 3ae079f..2450b50 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 0016a3f..f236907 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 23da95f..e7a3058 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 0000000..ffac17b --- /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; |