decl.c (make_packable_type): Resize the last component to its RM size only if it...
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 1 May 2008 10:50:01 +0000 (10:50 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 1 May 2008 10:50:01 +0000 (10:50 +0000)
* decl.c (make_packable_type): Resize the last component to its RM size
only if it is of an aggregate type.
* trans.c (call_to_gnu): Fix nit in comment.
(gnat_to_gnu): Likewise.

From-SVN: r134848

gcc/ada/ChangeLog
gcc/ada/decl.c
gcc/ada/trans.c

index 0bff31599a1d4e6c01b06d51f274866c88f1c46f..b1f1a6c03126c8ee5b354ce919e0b024d2bf0363 100644 (file)
@@ -1,3 +1,10 @@
+2008-05-01  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * decl.c (make_packable_type): Resize the last component to its RM size
+       only if it is of an aggregate type.
+       * trans.c (call_to_gnu): Fix nit in comment.
+       (gnat_to_gnu): Likewise.
+
 2008-04-30  Samuel Tardieu  <sam@rfc1149.net>
 
        * Makefile.in: Adapt sh4-linux target.
index 991faae49e1d79acf95d1e0a07ee6a3652439a5b..8dec1be15127999df8517593f73c9fb935f1a8c3 100644 (file)
@@ -5487,9 +5487,8 @@ make_packable_type (tree type, bool in_record)
 
   TYPE_USER_ALIGN (new_type) = 1;
 
-  /* Now copy the fields, keeping the position and size as we don't
-     want to propagate packedness downward.  But make an exception
-     for the last field in order to ditch the padding bits.  */
+  /* Now copy the fields, keeping the position and size as we don't want
+     to change the layout by propagating the packedness downwards.  */
   for (old_field = TYPE_FIELDS (type); old_field;
        old_field = TREE_CHAIN (old_field))
     {
@@ -5503,8 +5502,18 @@ make_packable_type (tree type, bool in_record)
          && host_integerp (TYPE_SIZE (new_field_type), 1))
        new_field_type = make_packable_type (new_field_type, true);
 
-      if (!TREE_CHAIN (old_field) && !TYPE_PACKED (type))
-       new_size = rm_size (new_field_type);
+      /* However, for the last field in a not already packed record type
+        that is of an aggregate type, we need to use the RM_Size in the
+        packable version of the record type, see finish_record_type.  */
+      if (!TREE_CHAIN (old_field)
+         && !TYPE_PACKED (type)
+         && (TREE_CODE (new_field_type) == RECORD_TYPE
+             || TREE_CODE (new_field_type) == UNION_TYPE
+             || TREE_CODE (new_field_type) == QUAL_UNION_TYPE)
+         && !TYPE_IS_FAT_POINTER_P (new_field_type)
+         && !TYPE_CONTAINS_TEMPLATE_P (new_field_type)
+         && TYPE_ADA_SIZE (new_field_type))
+       new_size = TYPE_ADA_SIZE (new_field_type);
       else
        new_size = DECL_SIZE (old_field);
 
index 07bdc69a4e4a0c317ea31e08d85dd3f831dc1c47..404b42f2282257af330056a5e82cd4e739f91ab7 100644 (file)
@@ -2204,7 +2204,7 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
             of the object if they are distinct, because the expectations
             of the callee would otherwise not be met:
               - if it's a justified modular type,
-              - if the actual type is a packed version of it.  */
+              - if the actual type is a packable version of it.  */
          else if (TREE_CODE (gnu_name_type) == RECORD_TYPE
                   && (TYPE_JUSTIFIED_MODULAR_P (gnu_name_type)
                       || larger_record_type_p (gnu_name_type,
@@ -4902,7 +4902,7 @@ gnat_to_gnu (Node_Id gnat_node)
          type wrong due to "instantiating" the unconstrained record with
          discriminant values.  Similarly, if the two types are record types
          with the same name don't convert.  This will be the case when we are
-         converting from a packed version of a type to its original type and
+         converting from a packable version of a type to its original type and
          we need those conversions to be NOPs in order for assignments into
          these types to work properly.