diff options
Diffstat (limited to 'gcc/ada/utils.c')
-rw-r--r-- | gcc/ada/utils.c | 28 |
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); |