===================================================================
@@ -4130,9 +4130,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gn
gnu_name
= convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_name))), gnu_name);
- /* If we have not saved a GCC object for the formal, it means it is an
- Out parameter not passed by reference and that need not be copied in.
- Otherwise, first see if the parameter is passed by reference. */
+ /* First see if the parameter is passed by reference. */
if (is_true_formal_parm && DECL_BY_REF_P (gnu_formal))
{
if (Ekind (gnat_formal) != E_In_Parameter)
@@ -4178,6 +4176,9 @@ Call_to_gnu (Node_Id gnat_node, tree *gn
gnu_formal_type = TREE_TYPE (gnu_formal);
gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual);
}
+
+ /* Then see if the parameter is an array passed to a foreign convention
+ subprogram. */
else if (is_true_formal_parm && DECL_BY_COMPONENT_PTR_P (gnu_formal))
{
gnu_formal_type = TREE_TYPE (gnu_formal);
@@ -4198,6 +4199,8 @@ Call_to_gnu (Node_Id gnat_node, tree *gn
but this is the most likely to work in all cases. */
gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual);
}
+
+ /* Then see if the parameter is passed by descriptor. */
else if (is_true_formal_parm && DECL_BY_DESCRIPTOR_P (gnu_formal))
{
gnu_actual = convert (gnu_formal_type, gnu_actual);
@@ -4214,6 +4217,8 @@ Call_to_gnu (Node_Id gnat_node, tree *gn
(TREE_TYPE (TREE_TYPE (gnu_formal)),
gnu_actual, gnat_actual));
}
+
+ /* Otherwise the parameter is passed by copy. */
else
{
tree gnu_size;
@@ -4221,11 +4226,18 @@ Call_to_gnu (Node_Id gnat_node, tree *gn
if (Ekind (gnat_formal) != E_In_Parameter)
gnu_name_list = tree_cons (NULL_TREE, gnu_name, gnu_name_list);
+ /* If we didn't create a PARM_DECL for the formal, this means that
+ it is an Out parameter not passed by reference and that need not
+ be copied in. In this case, the value of the actual need not be
+ read. However, we still need to make sure that its side-effects
+ are evaluated before the call, so we evaluate its address. */
if (!is_true_formal_parm)
{
- /* Make sure side-effects are evaluated before the call. */
if (TREE_SIDE_EFFECTS (gnu_name))
- append_to_statement_list (gnu_name, &gnu_stmt_list);
+ {
+ tree addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_name);
+ append_to_statement_list (addr, &gnu_stmt_list);
+ }
continue;
}