From patchwork Tue Jan 29 22:36:50 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Fortran] PR56138 - fix deferred-length character funcs w/o result variable From: Tobias Burnus X-Patchwork-Id: 216678 Message-Id: <51084F02.6060903@net-b.de> To: gcc patches , gfortran Date: Tue, 29 Jan 2013 23:36:50 +0100 For allocatable string lengths (deferred length strings), the current code generates a local integer variable to which the the length is assigned. For some reason, that doesn't work for some functions which do not use a result variable - leading to failures as the pass-by-reference variable is not dereferenced. That's fixed by the attached patch. I have to admit that I do not understand why it works without the patch for the examples in gfortran.dg/allocatable_function_5.f90, where - for some tests - also no result variable is used. Build and regtested on x86-64-gnu-linux. OK for the trunk? Tobias 2012-01-29 Tobias Burnus PR fortran/56138 * trans-decl.c (gfc_trans_deferred_vars): Fix deferred-length results for functions without extra result variable. 2012-01-29 Tobias Burnus PR fortran/56138 * gfortran.dg/allocatable_function_6.f90: New. diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 1d0919d..7732440 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -3775,7 +3775,7 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block) null_pointer_node)); } - if ((sym->attr.dummy ||sym->attr.result) + if ((sym->attr.dummy || sym->attr.result || sym->result == sym) && sym->ts.type == BT_CHARACTER && sym->ts.deferred) { diff --git a/gcc/testsuite/gfortran.dg/allocatable_function_6.f90 b/gcc/testsuite/gfortran.dg/allocatable_function_6.f90 new file mode 100644 index 0000000..4255009 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/allocatable_function_6.f90 @@ -0,0 +1,22 @@ +! { dg-do run } +! +! PR fortran/56138 +! +! Contributed by John Chludzinski, using the code of John Reid +! +implicit none +CHARACTER(LEN=:),ALLOCATABLE :: str +if (s_to_c("ABCdef") /= "ABCdef" .or. len(s_to_c("ABCdef")) /= 6) call abort() +str = s_to_c("ABCdef") +if (str /= "ABCdef" .or. len(str) /= 6) call abort() +str(1:3) = s_to_c("123") +if (str /= "123def" .or. len(str) /= 6) call abort() + +contains + +PURE FUNCTION s_to_c(string) + CHARACTER(LEN=*),INTENT(IN) :: string + CHARACTER(LEN=:),ALLOCATABLE :: s_to_c + s_to_c = string +ENDFUNCTION s_to_c +end