aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/utils.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2008-05-03 19:35:01 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2008-05-03 19:35:01 +0000
commit88f36b7eb6a153a914e9b4d678c1ddaddb842747 (patch)
tree8c9f10498aa285c5cda1ea869b4f8d07d9999b77 /gcc/ada/utils.c
parent093daf0fc7ddbde9214ae6cca049bb80fa7d65ab (diff)
downloadgcc-88f36b7eb6a153a914e9b4d678c1ddaddb842747.zip
gcc-88f36b7eb6a153a914e9b4d678c1ddaddb842747.tar.gz
gcc-88f36b7eb6a153a914e9b4d678c1ddaddb842747.tar.bz2
decl.c (maybe_pad_type): Try to get a form of the type with integral mode even if...
* decl.c (maybe_pad_type): Try to get a form of the type with integral mode even if the alignment is not a factor of the original size. But make sure to create the inner field with the original size. Reorder. * trans.c (addressable_p) <COMPONENT_REF>: Treat the field of a padding record as always addressable. * utils.c (convert): Deal specially with conversions between original and packable versions of a record type. * utils2.c (build_binary_op) <MODIFY_EXPR>: Be more restrictive when recognizing an assignment between padded objects. From-SVN: r134916
Diffstat (limited to 'gcc/ada/utils.c')
-rw-r--r--gcc/ada/utils.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c
index d6a2234..8d3df68 100644
--- a/gcc/ada/utils.c
+++ b/gcc/ada/utils.c
@@ -3396,7 +3396,9 @@ convert (tree type, tree expr)
&& TYPE_IS_PADDING_P (type) && TYPE_IS_PADDING_P (etype)
&& (!TREE_CONSTANT (TYPE_SIZE (type))
|| !TREE_CONSTANT (TYPE_SIZE (etype))
- || gnat_types_compatible_p (type, etype)))
+ || gnat_types_compatible_p (type, etype)
+ || TYPE_NAME (TREE_TYPE (TYPE_FIELDS (type)))
+ == TYPE_NAME (TREE_TYPE (TYPE_FIELDS (etype)))))
;
/* If the output type has padding, convert to the inner type and
@@ -3405,9 +3407,13 @@ convert (tree type, tree expr)
{
/* If we previously converted from another type and our type is
of variable size, remove the conversion to avoid the need for
- variable-size temporaries. */
+ variable-size temporaries. Likewise for a conversion between
+ original and packable version. */
if (TREE_CODE (expr) == VIEW_CONVERT_EXPR
- && !TREE_CONSTANT (TYPE_SIZE (type)))
+ && (!TREE_CONSTANT (TYPE_SIZE (type))
+ || (ecode == RECORD_TYPE
+ && TYPE_NAME (etype)
+ == TYPE_NAME (TREE_TYPE (TREE_OPERAND (expr, 0))))))
expr = TREE_OPERAND (expr, 0);
/* If we are just removing the padding from expr, convert the original
@@ -3419,7 +3425,10 @@ convert (tree type, tree expr)
&& TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
&& (!TREE_CONSTANT (TYPE_SIZE (type))
|| gnat_types_compatible_p (type,
- TREE_TYPE (TREE_OPERAND (expr, 0)))))
+ TREE_TYPE (TREE_OPERAND (expr, 0)))
+ || (ecode == RECORD_TYPE
+ && TYPE_NAME (etype)
+ == TYPE_NAME (TREE_TYPE (TYPE_FIELDS (type))))))
return convert (type, TREE_OPERAND (expr, 0));
/* If the result type is a padded type with a self-referentially-sized
@@ -3534,8 +3543,12 @@ convert (tree type, tree expr)
case CONSTRUCTOR:
/* If we are converting a CONSTRUCTOR to a mere variant type, just make
- a new one in the proper type. */
- if (gnat_types_compatible_p (type, etype))
+ a new one in the proper type. Likewise for a conversion between
+ original and packable version. */
+ if (code == ecode
+ && (gnat_types_compatible_p (type, etype)
+ || (code == RECORD_TYPE
+ && TYPE_NAME (type) == TYPE_NAME (etype))))
{
expr = copy_node (expr);
TREE_TYPE (expr) = type;
@@ -3617,7 +3630,8 @@ convert (tree type, tree expr)
/* If we're converting between two aggregate types that are mere
variants, just make a VIEW_CONVERT_EXPR. */
- else if (AGGREGATE_TYPE_P (type)
+ else if (code == ecode
+ && AGGREGATE_TYPE_P (type)
&& gnat_types_compatible_p (type, etype))
return build1 (VIEW_CONVERT_EXPR, type, expr);