This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gfortran] Fix PR15129: Assumed length character length handled wrongly


PR 15129 deals with a funny issue:
   SUBROUTINE (A, B, C)
   CHARACTER(*) :: A, B
   CHARACTER(*) :: C
   PRINT *, LEN(A) - LEN(B)
   END SUBROUTINE
would always print zero. This is because character declarations on the
same line share the same gfc_charlen structure, which makes sense if not
dealing with assumed length strings.

The fix involves simply creating a new gfc_charlen structure for every
assumed length variable. In order to avoid memory leakage this has to be
chained into the list of exisitng charlen's, so we can't simply create a
new one unconditionally, but this is easily fixed.

Built and tested on i686-pc-linux, I attached a new testcase which I
plan to add to the testsuite.

- Tobi

2004-07-15  Tobias Schlueter  <tobias.schlueter@physik.uni-muenchen.de>

	PR fortran/15129
	* trans-decl.c (gfc_build_function_decl): Create a new chardecl
	for every assumed length character dummy argument.

Index: trans-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-decl.c,v
retrieving revision 1.22
diff -u -p -r1.22 trans-decl.c
--- trans-decl.c        12 Jul 2004 01:23:36 -0000      1.22
+++ trans-decl.c        15 Jul 2004 15:40:26 -0000
@@ -1180,7 +1182,25 @@ gfc_build_function_decl (gfc_symbol * sy
           if (!f->sym->ts.cl->length)
            {
              TREE_USED (length) = 1;
-             f->sym->ts.cl->backend_decl = length;
+             if (!f->sym->ts.cl->backend_decl)
+               f->sym->ts.cl->backend_decl = length;
+             else
+               {
+                 /* there is already another variable using this
+                    gfc_charlen node, build a new one for this variable
+                    and chain it into the list of gfc_charlens.
+                    This happens for e.g. in the case
+                      CHARACTER(*)::c1,c2
+                    since CHARACTER declarations on the same line share
+                    the same gfc_charlen node.  */
+                 gfc_charlen *cl;
+
+                 cl = gfc_get_charlen ();
+                 cl->backend_decl = length;
+                 cl->next = f->sym->ts.cl->next;
+                 f->sym->ts.cl->next = cl;
+                 f->sym->ts.cl = cl;
+               }
            }

           parm = TREE_CHAIN (parm);


! { dg-do run }
! PR 15129: we used to share the character length between A and B in the 
! subroutine.
CHARACTER*10 A
CHARACTER*8 B
A = 'gfortran'
B = 'rocks!'
CALL T(A,B)
contains
SUBROUTINE T(A,B)
CHARACTER*(*) A,B
if(len(a)/=10) call abort()
if(len(b)/=8) call abort()
END SUBROUTINE
end

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]