diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-04-30 08:31:29 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-04-30 08:31:29 +0000 |
commit | 147e30365c4839d481ac22141667a23ceb66c610 (patch) | |
tree | 344606836405cdc8b8aabc044d626774a697e93e | |
parent | 81f9f420f6b92ceb22d0c493d4186d2b48dd2bff (diff) | |
download | gcc-147e30365c4839d481ac22141667a23ceb66c610.tar.gz |
* gcc-interface/decl.c (gnat_to_gnu_entity): In type annotation mode,
do not adjust the size of a tagged type if there is a representation
clause on it. Otherwise, round the adjustment up to the alignment
of the first field and use the appropriate helper routine.
(maybe_pad_type): Do not warn in type annotation mode on a tagged type.
(gnat_to_gnu_field): Do not error out under the same circumstances.
(annotate_rep): In type annotation mode, do not adjust the offset of
components of a tagged type with representation clause. Otherwise,
round the adjustment up to the alignment of the first field.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186961 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ada/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 64 |
2 files changed, 55 insertions, 23 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 838e4d0f6a8..31d5ac41874 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,17 @@ 2012-04-30 Eric Botcazou <ebotcazou@adacore.com> + * gcc-interface/decl.c (gnat_to_gnu_entity): In type annotation mode, + do not adjust the size of a tagged type if there is a representation + clause on it. Otherwise, round the adjustment up to the alignment + of the first field and use the appropriate helper routine. + (maybe_pad_type): Do not warn in type annotation mode on a tagged type. + (gnat_to_gnu_field): Do not error out under the same circumstances. + (annotate_rep): In type annotation mode, do not adjust the offset of + components of a tagged type with representation clause. Otherwise, + round the adjustment up to the alignment of the first field. + +2012-04-30 Eric Botcazou <ebotcazou@adacore.com> + * gcc-interface/utils.c (finish_record_type): Force the traditional GCC layout for bitfields on the type if it is packed or has a representation clause and an alternate layout is available. @@ -14,7 +26,7 @@ (destroy_dummy_type): Likewise. * gcc-interface/trans.c (gnat_validate_uc_list): New variable. (gigi): Call validate_unchecked_conversion on gnat_validate_uc_list - after the translation is completed. Call destroy_gnat_to_gnu and + after the translation is completed. Call destroy_gnat_to_gnu and destroy_dummy_type at the end. (Subprogram_Body_to_gnu): Do not call mark_out_of_scope. (gnat_to_gnu) <N_Block_Statement>: Likewise. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 6f351d3db2e..333d33b307e 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -5027,28 +5027,33 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) if (CONTAINS_PLACEHOLDER_P (gnu_size)) gnu_size = max_size (gnu_size, true); - if (type_annotate_only && Is_Tagged_Type (gnat_entity)) + /* If we are just annotating types and the type is tagged, the tag + and the parent components are not generated by the front-end so + sizes must be adjusted if there is no representation clause. */ + if (type_annotate_only + && Is_Tagged_Type (gnat_entity) + && !VOID_TYPE_P (gnu_type) + && (!TYPE_FIELDS (gnu_type) + || integer_zerop (bit_position (TYPE_FIELDS (gnu_type))))) { - /* In this mode, the tag and the parent components are not - generated by the front-end so the sizes must be adjusted. */ tree pointer_size = bitsize_int (POINTER_SIZE), offset; Uint uint_size; if (Is_Derived_Type (gnat_entity)) { - offset = UI_To_gnu (Esize (Etype (Base_Type (gnat_entity))), - bitsizetype); - Set_Alignment (gnat_entity, - Alignment (Etype (Base_Type (gnat_entity)))); + Entity_Id gnat_parent = Etype (Base_Type (gnat_entity)); + offset = UI_To_gnu (Esize (gnat_parent), bitsizetype); + Set_Alignment (gnat_entity, Alignment (gnat_parent)); } else offset = pointer_size; + if (TYPE_FIELDS (gnu_type)) + offset + = round_up (offset, DECL_ALIGN (TYPE_FIELDS (gnu_type))); + gnu_size = size_binop (PLUS_EXPR, gnu_size, offset); - gnu_size = size_binop (MULT_EXPR, pointer_size, - size_binop (CEIL_DIV_EXPR, - gnu_size, - pointer_size)); + gnu_size = round_up (gnu_size, POINTER_SIZE); uint_size = annotate_value (gnu_size); Set_Esize (gnat_entity, uint_size); Set_RM_Size (gnat_entity, uint_size); @@ -6619,7 +6624,9 @@ maybe_pad_type (tree type, tree size, unsigned int align, /* If the size was widened explicitly, maybe give a warning. Take the original size as the maximum size of the input if there was an unconstrained record involved and round it up to the specified alignment, - if one was specified. */ + if one was specified. But don't do it if we are just annotating types + and the type is tagged, since tagged types aren't fully laid out in this + mode. */ if (CONTAINS_PLACEHOLDER_P (orig_size)) orig_size = max_size (orig_size, true); @@ -6635,7 +6642,8 @@ maybe_pad_type (tree type, tree size, unsigned int align, && TREE_CODE (orig_size) == INTEGER_CST && (TREE_OVERFLOW (size) || TREE_OVERFLOW (orig_size) - || tree_int_cst_lt (size, orig_size)))) + || tree_int_cst_lt (size, orig_size))) + && !(type_annotate_only && Is_Tagged_Type (Etype (gnat_entity)))) { Node_Id gnat_error_node = Empty; @@ -6901,10 +6909,13 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, } } - /* If this field needs strict alignment, ensure the record is - sufficiently aligned and that that position and size are - consistent with the alignment. */ - if (needs_strict_alignment) + /* If this field needs strict alignment, check that the record is + sufficiently aligned and that position and size are consistent + with the alignment. But don't do it if we are just annotating + types and the field's type is tagged, since tagged types aren't + fully laid out in this mode. */ + if (needs_strict_alignment + && !(type_annotate_only && Is_Tagged_Type (gnat_field_type))) { TYPE_ALIGN (gnu_record_type) = MAX (TYPE_ALIGN (gnu_record_type), TYPE_ALIGN (gnu_field_type)); @@ -7839,12 +7850,16 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type) { tree parent_offset; - if (type_annotate_only && Is_Tagged_Type (gnat_entity)) + /* If we are just annotating types and the type is tagged, the tag + and the parent components are not generated by the front-end so + we need to add the appropriate offset to each component without + representation clause. */ + if (type_annotate_only + && Is_Tagged_Type (gnat_entity) + && No (Component_Clause (gnat_field))) { - /* In this mode the tag and parent components are not - generated, so we add the appropriate offset to each - component. For a component appearing in the current - extension, the offset is the size of the parent. */ + /* For a component appearing in the current extension, the + offset is the size of the parent. */ if (Is_Derived_Type (gnat_entity) && Original_Record_Component (gnat_field) == gnat_field) parent_offset @@ -7852,6 +7867,11 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type) bitsizetype); else parent_offset = bitsize_int (POINTER_SIZE); + + if (TYPE_FIELDS (gnu_type)) + parent_offset + = round_up (parent_offset, + DECL_ALIGN (TYPE_FIELDS (gnu_type))); } else parent_offset = bitsize_zero_node; |