aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2017-05-15 08:00:41 +0000
committerEric Botcazou <ebotcazou@adacore.com>2017-05-15 08:00:41 +0000
commit9cb9f69dcb4a3a6f031cc94d76307c8044dde97a (patch)
tree7db7d7873d883dbf77ccfcf3bcc36170a3139c3d
parent792242dc622a33f819566b10adc9536e034b2b67 (diff)
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Type>: When there
is a representation clause on an extension, propagate the alignment of the parent type only if the platform requires strict alignment. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@248049 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ada/ChangeLog6
-rw-r--r--gcc/ada/gcc-interface/decl.c16
2 files changed, 20 insertions, 2 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 0dd6d04bc7c..dc2916e5278 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,9 @@
+2017-05-15 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Type>: When there
+ is a representation clause on an extension, propagate the alignment of
+ the parent type only if the platform requires strict alignment.
+
2017-05-12 Eric Botcazou <ebotcazou@adacore.com>
* system-linux-arm.ads (Memory_Size): Use Long_Integer'Size
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index af4574d2c62..b39b75a852b 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -204,6 +204,7 @@ static tree elaborate_expression_2 (tree, Entity_Id, const char *, bool, bool,
static tree elaborate_reference (tree, Entity_Id, bool, tree *);
static tree gnat_to_gnu_component_type (Entity_Id, bool, bool);
static tree gnat_to_gnu_subprog_type (Entity_Id, bool, bool, tree *);
+static int adjust_packed (tree, tree, int);
static tree gnat_to_gnu_field (Entity_Id, tree, int, bool, bool);
static tree gnu_ext_name_for_subprog (Entity_Id, tree);
static tree change_qualified_type (tree, int);
@@ -3094,6 +3095,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
Entity_Id gnat_parent = Parent_Subtype (gnat_entity);
tree gnu_dummy_parent_type = make_node (RECORD_TYPE);
tree gnu_parent;
+ int parent_packed = 0;
/* A major complexity here is that the parent subtype will
reference our discriminants in its Stored_Constraint list.
@@ -3172,7 +3174,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
be created with a component clause below, then we need
to apply the same adjustment as in gnat_to_gnu_field. */
if (has_rep && TYPE_ALIGN (gnu_type) < TYPE_ALIGN (gnu_parent))
- SET_TYPE_ALIGN (gnu_type, TYPE_ALIGN (gnu_parent));
+ {
+ /* ??? For historical reasons, we do it on strict-alignment
+ platforms only, where it is really required. This means
+ that a confirming representation clause will change the
+ behavior of the compiler on the other platforms. */
+ if (STRICT_ALIGNMENT)
+ SET_TYPE_ALIGN (gnu_type, TYPE_ALIGN (gnu_parent));
+ else
+ parent_packed
+ = adjust_packed (gnu_parent, gnu_type, parent_packed);
+ }
/* Finally we fix up both kinds of twisted COMPONENT_REF we have
initially built. The discriminants must reference the fields
@@ -3218,7 +3230,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
? TYPE_SIZE (gnu_parent) : NULL_TREE,
has_rep
? bitsize_zero_node : NULL_TREE,
- 0, 1);
+ parent_packed, 1);
DECL_INTERNAL_P (gnu_field) = 1;
TREE_OPERAND (gnu_get_parent, 1) = gnu_field;
TYPE_FIELDS (gnu_type) = gnu_field;