diff options
author | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2012-11-23 10:42:50 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2012-11-23 10:42:50 +0000 |
commit | 29e100b31a77dcee0c57f7438e3a71007b18b52b (patch) | |
tree | 9dbc2f03652be5a6d21b9de8d0f15736f32e9aae /gcc/ada | |
parent | 1076781c1f312bf3ac2d19844b484b0ef0ca9c5d (diff) | |
download | gcc-29e100b31a77dcee0c57f7438e3a71007b18b52b.zip gcc-29e100b31a77dcee0c57f7438e3a71007b18b52b.tar.gz gcc-29e100b31a77dcee0c57f7438e3a71007b18b52b.tar.bz2 |
decl.c (components_need_strict_alignment): New.
* gcc-interface/decl.c (components_need_strict_alignment): New.
(components_to_record): Do not pack the variants if one of the fields
needs strict alignment. Likewise for the variant part as a whole.
Specify the position of the variants even if the size isn't specified,
but do not specify the size of the variant part in this case.
From-SVN: r193750
Diffstat (limited to 'gcc/ada')
-rw-r--r-- | gcc/ada/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 52 |
2 files changed, 54 insertions, 9 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 9b5eabd..b835918 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,8 +1,15 @@ +2012-11-23 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.c (components_need_strict_alignment): New. + (components_to_record): Do not pack the variants if one of the fields + needs strict alignment. Likewise for the variant part as a whole. + Specify the position of the variants even if the size isn't specified, + but do not specify the size of the variant part in this case. + 2012-11-20 Diego Novillo <dnovillo@google.com> Jakub Jelinek <jakub@redhat.com> - * gcc-interface/decl.c: Replace all vec<T,A>() - initializers with vNULL. + * gcc-interface/decl.c: Replace all vec<T,A>() initializers with vNULL. 2012-11-18 Eric Botcazou <ebotcazou@adacore.com> diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 88afccf..a5205ce 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -6650,6 +6650,30 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, return gnu_field; } +/* Return true if at least one member of COMPONENT_LIST needs strict + alignment. */ + +static bool +components_need_strict_alignment (Node_Id component_list) +{ + Node_Id component_decl; + + for (component_decl = First_Non_Pragma (Component_Items (component_list)); + Present (component_decl); + component_decl = Next_Non_Pragma (component_decl)) + { + Entity_Id gnat_field = Defining_Entity (component_decl); + + if (Is_Aliased (gnat_field)) + return True; + + if (Strict_Alignment (Etype (gnat_field))) + return True; + } + + return False; +} + /* Return true if TYPE is a type with variable size or a padding type with a field of variable size or a record that has a field with such a type. */ @@ -6880,6 +6904,7 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list, "XVN"); tree gnu_union_type, gnu_union_name; tree this_first_free_pos, gnu_variant_list = NULL_TREE; + bool union_field_needs_strict_alignment = false; if (TREE_CODE (gnu_name) == TYPE_DECL) gnu_name = DECL_NAME (gnu_name); @@ -6980,8 +7005,18 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list, else { /* Deal with packedness like in gnat_to_gnu_field. */ - int field_packed - = adjust_packed (gnu_variant_type, gnu_record_type, packed); + bool field_needs_strict_alignment + = components_need_strict_alignment (Component_List (variant)); + int field_packed; + + if (field_needs_strict_alignment) + { + field_packed = 0; + union_field_needs_strict_alignment = true; + } + else + field_packed + = adjust_packed (gnu_variant_type, gnu_record_type, packed); /* Finalize the record type now. We used to throw away empty records but we no longer do that because we need @@ -6997,8 +7032,7 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list, gnu_union_type, all_rep_and_size ? TYPE_SIZE (gnu_variant_type) : 0, - all_rep_and_size - ? bitsize_zero_node : 0, + all_rep ? bitsize_zero_node : 0, field_packed, 0); DECL_INTERNAL_P (gnu_field) = 1; @@ -7041,12 +7075,16 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list, NULL, true, debug_info, gnat_component_list); /* Deal with packedness like in gnat_to_gnu_field. */ - union_field_packed - = adjust_packed (gnu_union_type, gnu_record_type, packed); + if (union_field_needs_strict_alignment) + union_field_packed = 0; + else + union_field_packed + = adjust_packed (gnu_union_type, gnu_record_type, packed); gnu_variant_part = create_field_decl (gnu_var_name, gnu_union_type, gnu_record_type, - all_rep ? TYPE_SIZE (gnu_union_type) : 0, + all_rep_and_size + ? TYPE_SIZE (gnu_union_type) : 0, all_rep || this_first_free_pos ? bitsize_zero_node : 0, union_field_packed, 0); |