@@ -1333,12 +1333,30 @@ gfc_get_symbol_decl (gfc_symbol * sym)
(sym->ts.u.cl->passed_length == sym->ts.u.cl->backend_decl))
sym->ts.u.cl->backend_decl = NULL_TREE;
- if (sym->ts.deferred && fun_or_res
- && sym->ts.u.cl->passed_length == NULL
- && sym->ts.u.cl->backend_decl)
+ if (sym->ts.deferred && byref)
{
- sym->ts.u.cl->passed_length = sym->ts.u.cl->backend_decl;
- sym->ts.u.cl->backend_decl = NULL_TREE;
+ /* The string length of a deferred char array is stored in the
+ parameter at sym->ts.u.cl->backend_decl as a reference and
+ marked as a result. Exempt this variable from generating a
+ temporary for it. */
+ if (sym->attr.result)
+ {
+ /* 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->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. */
+ else if (sym->attr.function
+ && sym->ts.u.cl->passed_length == NULL
+ && sym->ts.u.cl->backend_decl)
+ {
+ sym->ts.u.cl->passed_length = sym->ts.u.cl->backend_decl;
+ sym->ts.u.cl->backend_decl = NULL_TREE;
+ }
}
if (sym->ts.u.cl->backend_decl == NULL_TREE)
@@ -2,15 +2,20 @@
!
! PR fortran/51055
! PR fortran/49110
-!
+! PR fortran/60334
subroutine test()
implicit none
integer :: i = 5
character(len=:), allocatable :: s1
+ character(len=:), pointer :: s2
+ character(len=5), target :: fifeC = 'FIVEC'
call sub(s1, i)
if (len(s1) /= 5) call abort()
if (s1 /= "ZZZZZ") call abort()
+ s2 => subfunc()
+ if (len(s2) /= 5) call abort()
+ if (s2 /= "FIVEC") call abort()
contains
subroutine sub(str,j)
character(len=:), allocatable :: str
@@ -19,6 +24,12 @@ contains
if (len(str) /= 5) call abort()
if (str /= "ZZZZZ") call abort()
end subroutine sub
+ function subfunc() result(res)
+ character(len=:), pointer :: res
+ res => fifec
+ if (len(res) /= 5) call abort()
+ if (res /= "FIVEC") call abort()
+ end function subfunc
end subroutine test
program a