aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2021-09-27 22:44:59 +0200
committerPierre-Marie de Rodat <derodat@adacore.com>2021-10-11 13:38:13 +0000
commit92961bdf2dfc63965a05302aac6c907065bd2c27 (patch)
tree593eaa3c7ec79eb171dead891b8731c91e86e2c7 /gcc/ada/gcc-interface/decl.c
parent547513eeab951fddeb53baaa577de32dc8b779de (diff)
downloadgcc-92961bdf2dfc63965a05302aac6c907065bd2c27.zip
gcc-92961bdf2dfc63965a05302aac6c907065bd2c27.tar.gz
gcc-92961bdf2dfc63965a05302aac6c907065bd2c27.tar.bz2
[Ada] Fix incorrect size for pathological pass-by-copy parameters
gcc/ada/ * gcc-interface/decl.c (gnat_to_gnu_param): Strip padding types only if the size does not change in the process. Rename local variable and add bypass for initialization procedures.
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 13e9004..5e42dd9 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -5403,19 +5403,21 @@ gnat_to_gnu_param (Entity_Id gnat_param, tree gnu_param_type, bool first,
mech = Default;
}
- /* If this is either a foreign function or if the underlying type won't
- be passed by reference and is as aligned as the original type, strip
- off possible padding type. */
+ /* Either for foreign conventions, or if the underlying type is not passed
+ by reference and is as large and aligned as the original type, strip off
+ a possible padding type. */
if (TYPE_IS_PADDING_P (gnu_param_type))
{
- tree unpadded_type = TREE_TYPE (TYPE_FIELDS (gnu_param_type));
+ tree inner_type = TREE_TYPE (TYPE_FIELDS (gnu_param_type));
if (foreign
|| (mech != By_Reference
- && !must_pass_by_ref (unpadded_type)
- && (mech == By_Copy || !default_pass_by_ref (unpadded_type))
- && TYPE_ALIGN (unpadded_type) >= TYPE_ALIGN (gnu_param_type)))
- gnu_param_type = unpadded_type;
+ && !must_pass_by_ref (inner_type)
+ && (mech == By_Copy || !default_pass_by_ref (inner_type))
+ && ((TYPE_SIZE (inner_type) == TYPE_SIZE (gnu_param_type)
+ && TYPE_ALIGN (inner_type) >= TYPE_ALIGN (gnu_param_type))
+ || Is_Init_Proc (gnat_subprog))))
+ gnu_param_type = inner_type;
}
/* For foreign conventions, pass arrays as pointers to the element type.