aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/trans-decl.c')
-rw-r--r--gcc/fortran/trans-decl.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 929cbda..a0305a6 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -1377,8 +1377,8 @@ gfc_get_symbol_decl (gfc_symbol * sym)
&& TREE_CODE (sym->ts.u.cl->backend_decl) == PARM_DECL)
{
sym->ts.u.cl->passed_length = sym->ts.u.cl->backend_decl;
- sym->ts.u.cl->backend_decl = NULL_TREE;
- length = gfc_create_string_length (sym);
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (sym->ts.u.cl->passed_length)));
+ sym->ts.u.cl->backend_decl = build_fold_indirect_ref (sym->ts.u.cl->backend_decl);
}
fun_or_res = byref && (sym->attr.result
@@ -1420,9 +1420,12 @@ gfc_get_symbol_decl (gfc_symbol * sym)
/* We need to insert a indirect ref for param decls. */
if (sym->ts.u.cl->backend_decl
&& TREE_CODE (sym->ts.u.cl->backend_decl) == PARM_DECL)
+ {
+ sym->ts.u.cl->passed_length = sym->ts.u.cl->backend_decl;
sym->ts.u.cl->backend_decl =
build_fold_indirect_ref (sym->ts.u.cl->backend_decl);
}
+ }
/* For all other parameters make sure, that they are copied so
that the value and any modifications are local to the routine
by generating a temporary variable. */
@@ -1431,6 +1434,10 @@ gfc_get_symbol_decl (gfc_symbol * sym)
&& sym->ts.u.cl->backend_decl)
{
sym->ts.u.cl->passed_length = sym->ts.u.cl->backend_decl;
+ if (POINTER_TYPE_P (TREE_TYPE (sym->ts.u.cl->passed_length)))
+ sym->ts.u.cl->backend_decl
+ = build_fold_indirect_ref (sym->ts.u.cl->backend_decl);
+ else
sym->ts.u.cl->backend_decl = NULL_TREE;
}
}
@@ -2264,6 +2271,13 @@ create_function_arglist (gfc_symbol * sym)
type = gfc_sym_type (arg);
arg->backend_decl = backend_decl;
type = build_reference_type (type);
+
+ if (POINTER_TYPE_P (len_type))
+ {
+ sym->ts.u.cl->passed_length = length;
+ sym->ts.u.cl->backend_decl =
+ build_fold_indirect_ref_loc (input_location, length);
+ }
}
}
@@ -2347,7 +2361,10 @@ create_function_arglist (gfc_symbol * sym)
if (f->sym->ts.u.cl->backend_decl == NULL
|| f->sym->ts.u.cl->backend_decl == length)
{
- if (f->sym->ts.u.cl->backend_decl == NULL)
+ if (POINTER_TYPE_P (len_type))
+ f->sym->ts.u.cl->backend_decl =
+ build_fold_indirect_ref_loc (input_location, length);
+ else if (f->sym->ts.u.cl->backend_decl == NULL)
gfc_create_string_length (f->sym);
/* Make sure PARM_DECL type doesn't point to incomplete type. */
@@ -3975,12 +3992,19 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
gfc_restore_backend_locus (&loc);
/* Pass back the string length on exit. */
+ tmp = proc_sym->ts.u.cl->backend_decl;
+ if (TREE_CODE (tmp) != INDIRECT_REF)
+ {
tmp = proc_sym->ts.u.cl->passed_length;
tmp = build_fold_indirect_ref_loc (input_location, tmp);
tmp = fold_convert (gfc_charlen_type_node, tmp);
tmp = fold_build2_loc (input_location, MODIFY_EXPR,
gfc_charlen_type_node, tmp,
proc_sym->ts.u.cl->backend_decl);
+ }
+ else
+ tmp = NULL_TREE;
+
gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
}
else if (TREE_CODE (proc_sym->ts.u.cl->backend_decl) == VAR_DECL)