Patchwork [Fortran] PR56138 - fix deferred-length character funcs w/o result variable

login
register
mail settings
Submitter Tobias Burnus
Date Jan. 29, 2013, 10:36 p.m.
Message ID <51084F02.6060903@net-b.de>
Download mbox | patch
Permalink /patch/216678/
State New
Headers show

Comments

Tobias Burnus - Jan. 29, 2013, 10:36 p.m.
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
Paul Richard Thomas - Jan. 30, 2013, 6:30 a.m.
Dear Tobias,

For a variety of reasons, I did not open my mailbox this morning but
got down to developing an almost identical fix and taking the PR!

Anyway, it would be best that you commit your fix, so it's OK for trunk.

Thanks

Paul

On 29 January 2013 23:36, Tobias Burnus <burnus@net-b.de> wrote:
> 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

Patch

2012-01-29  Tobias Burnus  <burnus@net-b.de>

	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  <burnus@net-b.de>

	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