gfc_string_to_single_character (tree len, tree str, int kind)
{
- if (!INTEGER_CST_P (len) || TREE_INT_CST_HIGH (len) != 0
+ if (len == NULL
+ || !INTEGER_CST_P (len) || TREE_INT_CST_HIGH (len) != 0
|| !POINTER_TYPE_P (TREE_TYPE (str)))
return NULL_TREE;
we take the character length of the first argument for the result.
For dummies, we have to look through the formal argument list for
this function and use the character length found there.*/
- if (ts.deferred && (sym->attr.allocatable || sym->attr.pointer))
+ if (ts.deferred)
cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
else if (!sym->attr.dummy)
cl.backend_decl = VEC_index (tree, stringargs, 0);
if (strcmp (formal->sym->name, sym->name) == 0)
cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
}
+ len = cl.backend_decl;
}
else
{
if ((!comp && sym->attr.allocatable)
|| (comp && comp->attr.allocatable))
- gfc_add_modify (&se->pre, var,
- fold_convert (TREE_TYPE (var),
- null_pointer_node));
+ {
+ gfc_add_modify (&se->pre, var,
+ fold_convert (TREE_TYPE (var),
+ null_pointer_node));
+ tmp = gfc_call_free (convert (pvoid_type_node, var));
+ gfc_add_expr_to_block (&se->post, tmp);
+ }
/* Provide an address expression for the function arguments. */
var = gfc_build_addr_expr (NULL_TREE, var);
VEC_safe_push (tree, gc, retargs, var);
}
- if (ts.type == BT_CHARACTER && ts.deferred
- && (sym->attr.allocatable || sym->attr.pointer))
+ /* Add the string length to the argument list. */
+ if (ts.type == BT_CHARACTER && ts.deferred)
{
tmp = len;
if (TREE_CODE (tmp) != VAR_DECL)
tmp = gfc_evaluate_now (len, &se->pre);
- len = gfc_build_addr_expr (NULL_TREE, tmp);
+ tmp = gfc_build_addr_expr (NULL_TREE, tmp);
+ VEC_safe_push (tree, gc, retargs, tmp);
}
-
- /* Add the string length to the argument list. */
- if (ts.type == BT_CHARACTER)
+ else if (ts.type == BT_CHARACTER)
VEC_safe_push (tree, gc, retargs, len);
}
gfc_free_interface_mapping (&mapping);
else
se->expr = var;
- if (!ts.deferred)
- se->string_length = len;
- else if (sym->attr.allocatable || sym->attr.pointer)
- se->string_length = cl.backend_decl;
+ se->string_length = len;
}
else
{
really added if -fbounds-check is enabled. Exclude deferred
character length lefthand sides. */
if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
- && !(expr1->ts.deferred
- && (TREE_CODE (lse.string_length) == VAR_DECL))
+ && !expr1->ts.deferred
&& !expr1->symtree->n.sym->attr.proc_pointer
&& !gfc_is_proc_ptr_comp (expr1, NULL))
{
/* The assignment to an deferred character length sets the string
length to that of the rhs. */
- if (expr1->ts.deferred && (TREE_CODE (lse.string_length) == VAR_DECL))
+ if (expr1->ts.deferred)
{
- if (expr2->expr_type != EXPR_NULL)
+ if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
gfc_add_modify (&block, lse.string_length, rse.string_length);
- else
+ else if (lse.string_length != NULL)
gfc_add_modify (&block, lse.string_length,
build_int_cst (gfc_charlen_type_node, 0));
}