aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@gcc.gnu.org>2012-11-23 10:42:50 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2012-11-23 10:42:50 +0000
commit29e100b31a77dcee0c57f7438e3a71007b18b52b (patch)
tree9dbc2f03652be5a6d21b9de8d0f15736f32e9aae /gcc/ada
parent1076781c1f312bf3ac2d19844b484b0ef0ca9c5d (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/ada/gcc-interface/decl.c52
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);