}
/* Make sure the backend_decl is present before accessing it. */
- if (expr->symtree->n.sym->backend_decl == NULL_TREE)
- expr->symtree->n.sym->backend_decl
- = gfc_get_symbol_decl (expr->symtree->n.sym);
- caf_decl = expr->symtree->n.sym->backend_decl;
- gcc_assert (caf_decl);
+ caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE
+ ? gfc_get_symbol_decl (expr->symtree->n.sym)
+ : expr->symtree->n.sym->backend_decl;
+
if (expr->symtree->n.sym->ts.type == BT_CLASS)
{
if (expr->ref && expr->ref->type == REF_ARRAY)
msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
"is less than one", name);
else
- msg = xasprintf ("Substring out of bounds: lower bound (%%ld)"
+ msg = xasprintf ("Substring out of bounds: lower bound (%%ld) "
"is less than one");
gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
fold_convert (long_integer_type_node,
if (se_expr)
se->expr = se_expr;
- /* Procedure actual arguments. */
- else if (sym->attr.flavor == FL_PROCEDURE
+ /* Procedure actual arguments. Look out for temporary variables
+ with the same attributes as function values. */
+ else if (!sym->attr.temporary
+ && sym->attr.flavor == FL_PROCEDURE
&& se->expr != current_function_decl)
{
if (!sym->attr.dummy && !sym->attr.proc_pointer)
if (fsym && fsym->attr.allocatable
&& fsym->attr.intent == INTENT_OUT)
{
+ if (fsym->ts.type == BT_DERIVED
+ && fsym->ts.u.derived->attr.alloc_comp)
+ {
+ // deallocate the components first
+ tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
+ parmse.expr, e->rank);
+ if (tmp != NULL_TREE)
+ gfc_add_expr_to_block (&se->pre, tmp);
+ }
+
tmp = build_fold_indirect_ref_loc (input_location,
parmse.expr);
if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
after use. This necessitates the creation of a temporary to
hold the result to prevent duplicate calls. */
if (!byref && sym->ts.type != BT_CHARACTER
- && sym->attr.allocatable && !sym->attr.dimension)
+ && ((sym->attr.allocatable && !sym->attr.dimension && !comp)
+ || (comp && comp->attr.allocatable && !comp->attr.dimension)))
{
tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
gfc_add_modify (&se->pre, tmp, se->expr);
gfc_add_block_to_block (&se->pre, &post);
/* Transformational functions of derived types with allocatable
- components must have the result allocatable components copied. */
+ components must have the result allocatable components copied when the
+ argument is actually given. */
arg = expr->value.function.actual;
if (result && arg && expr->rank
- && expr->value.function.isym
- && expr->value.function.isym->transformational
- && arg->expr->ts.type == BT_DERIVED
- && arg->expr->ts.u.derived->attr.alloc_comp)
+ && expr->value.function.isym
+ && expr->value.function.isym->transformational
+ && arg->expr
+ && arg->expr->ts.type == BT_DERIVED
+ && arg->expr->ts.u.derived->attr.alloc_comp)
{
tree tmp2;
/* Copy the allocatable components. We have to use a
{
if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
- else if (cm->attr.allocatable)
+ else if (cm->attr.allocatable || cm->attr.pdt_array)
{
tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
gfc_add_expr_to_block (&block, tmp);
&& (!c->expr || c->expr->expr_type == EXPR_NULL))
{
tree token, desc, size;
- symbol_attribute attr;
bool is_array = cm->ts.type == BT_CLASS
? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
}
else
{
- desc = gfc_conv_scalar_to_descriptor (&se, field, attr);
+ desc = gfc_conv_scalar_to_descriptor (&se, field,
+ cm->ts.type == BT_CLASS
+ ? CLASS_DATA (cm)->attr
+ : cm->attr);
size = TYPE_SIZE_UNIT (TREE_TYPE (field));
}
gfc_add_block_to_block (&block, &se.pre);
tree cond;
const char* msg;
+ tmp = INDIRECT_REF_P (lse.expr)
+ ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
+
/* We should only get array references here. */
- gcc_assert (TREE_CODE (lse.expr) == POINTER_PLUS_EXPR
- || TREE_CODE (lse.expr) == ARRAY_REF);
+ gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
+ || TREE_CODE (tmp) == ARRAY_REF);
/* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
or the array itself(ARRAY_REF). */
- tmp = TREE_OPERAND (lse.expr, 0);
+ tmp = TREE_OPERAND (tmp, 0);
/* Provide the address of the array. */
if (TREE_CODE (lse.expr) == ARRAY_REF)