aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/trans.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/gcc-interface/trans.cc')
-rw-r--r--gcc/ada/gcc-interface/trans.cc29
1 files changed, 22 insertions, 7 deletions
diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc
index e02804b..a7254fe 100644
--- a/gcc/ada/gcc-interface/trans.cc
+++ b/gcc/ada/gcc-interface/trans.cc
@@ -4049,7 +4049,7 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
tree gnu_decl;
/* Skip any entries that have been already filled in; they must
- correspond to In Out parameters. */
+ correspond to In Out parameters or previous Out parameters. */
while (gnu_cico_entry && TREE_VALUE (gnu_cico_entry))
gnu_cico_entry = TREE_CHAIN (gnu_cico_entry);
@@ -4059,11 +4059,22 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
if (DECL_BY_REF_P (gnu_decl))
gnu_decl = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_decl);
- /* Do any needed references for padded types. */
- TREE_VALUE (gnu_cico_entry)
- = convert (TREE_TYPE (TREE_PURPOSE (gnu_cico_entry)), gnu_decl);
+ TREE_VALUE (gnu_cico_entry) = gnu_decl;
}
+
+ /* Finally, ensure type consistency between TREE_PURPOSE and TREE_VALUE
+ so that the assignment of the latter to the former can be done. */
+ tree gnu_cico_entry = gnu_cico_list;
+ while (gnu_cico_entry)
+ {
+ if (!VOID_TYPE_P (TREE_VALUE (gnu_cico_entry)))
+ TREE_VALUE (gnu_cico_entry)
+ = convert (TREE_TYPE (TREE_PURPOSE (gnu_cico_entry)),
+ TREE_VALUE (gnu_cico_entry));
+ gnu_cico_entry = TREE_CHAIN (gnu_cico_entry);
+ }
}
+
else
vec_safe_push (gnu_return_label_stack, NULL_TREE);
@@ -4161,9 +4172,13 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
}
}
- /* Otherwise, if this is a procedure or a function which does not return
- by invisible reference, we can do a direct block-copy out. */
- else
+ /* Otherwise, if this is a procedure or a function that does not return
+ by invisible reference, we can do a direct block-copy out, but we do
+ not need to do it for a null initialization procedure when the _Init
+ parameter is not passed in since we would copy uninitialized bits. */
+ else if (!(Is_Null_Init_Proc (gnat_subprog)
+ && list_length (gnu_cico_list) == 1
+ && TREE_CODE (TREE_VALUE (gnu_cico_list)) == VAR_DECL))
{
tree gnu_retval;