@@ -5248,6 +5248,39 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
if (POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
parmse->expr = build_fold_indirect_ref_loc (input_location,
parmse->expr);
+ }
+ else
+ gfc_conv_expr (parmse, e);
+
+ if (POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
+ parmse->expr = build_fold_indirect_ref_loc (input_location,
+ parmse->expr);
+
+ /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
+ allocated on entry, it must be deallocated. */
+ if (fsym && fsym->attr.allocatable
+ && fsym->attr.intent == INTENT_OUT)
+ {
+ tmp = parmse->expr;
+
+ if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
+ tmp = gfc_conv_descriptor_data_get (tmp);
+ tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
+ NULL_TREE, NULL_TREE, true,
+ e,
+ GFC_CAF_COARRAY_NOCOARRAY);
+ if (fsym->attr.optional
+ && e->expr_type == EXPR_VARIABLE
+ && e->symtree->n.sym->attr.optional)
+ tmp = fold_build3_loc (input_location, COND_EXPR,
+ void_type_node,
+ gfc_conv_expr_present (e->symtree->n.sym),
+ tmp, build_empty_stmt (input_location));
+ gfc_add_expr_to_block (&parmse->pre, tmp);
+ }
+
+ if (e->rank != 0)
+ {
bool is_artificial = (INDIRECT_REF_P (parmse->expr)
? DECL_ARTIFICIAL (TREE_OPERAND (parmse->expr, 0))
: DECL_ARTIFICIAL (parmse->expr));
@@ -5293,16 +5326,8 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
}
}
else
- {
- gfc_conv_expr (parmse, e);
-
- if (POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
- parmse->expr = build_fold_indirect_ref_loc (input_location,
- parmse->expr);
-
parmse->expr = gfc_conv_scalar_to_descriptor (parmse,
parmse->expr, attr);
- }
/* Set the CFI attribute field through a temporary value for the
gfc attribute. */
@@ -6170,7 +6195,9 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
/* Implement F2018, C.12.6.1: paragraph (2). */
gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
- else if (e->expr_type == EXPR_VARIABLE
+ else
+ {
+ if (e->expr_type == EXPR_VARIABLE
&& is_subref_array (e)
&& !(fsym && fsym->attr.pointer))
/* The actual argument is a component reference to an
@@ -6219,7 +6246,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
/* Unallocated allocatable arrays and unassociated pointer arrays
need their dtype setting if they are argument associated with
assumed rank dummies. */
- if (!sym->attr.is_bind_c && e && fsym && fsym->as
+ if (e && fsym && fsym->as
&& fsym->as->type == AS_ASSUMED_RANK)
{
if (gfc_expr_attr (e).pointer
@@ -6256,10 +6283,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
}
tmp = parmse.expr;
- /* With bind(C), the actual argument is replaced by a bind-C
- descriptor; in this case, the data component arrives here,
- which shall not be dereferenced, but still freed and
- nullified. */
+
if (TREE_TYPE(tmp) != pvoid_type_node)
tmp = build_fold_indirect_ref_loc (input_location,
parmse.expr);
@@ -6280,6 +6304,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
}
}
}
+ }
/* The case with fsym->attr.optional is that of a user subroutine
with an interface indicating an optional argument. When we call