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]

[PATCH] Fix Fortran -fno-automatic and save_all (PR fortran/23677)


Hi!

This patch fixes 2 problems:
1) SAVE all would not save constant length CHARACTER variables,
   but unexpectedly non-constant length CHARACTER variables
   (gfortran.fortran-torture/execute/save_1.f90 test passes
   with g77, but fails with gfortran unless this patch is applied)
2) -fno-automatic would issue errors if some variable had explicit
   SAVE already.  g77 silently compiled it, so I think we should
   do the same.
Ok for HEAD/4.0?

2005-09-26  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/23677
	* symbol.c (gfc_is_var_automatic): Return true if character length
	is non-constant rather than constant.
	(maybe_save_symbol, gfc_no_automatic_save_all): New functions.
	* gfortran.h (gfc_no_automatic_save_all): New prototype.
	* resolve.c (gfc_resolve): Call gfc_no_automatic_save_all rather than
	gfc_save_all if -fno-automatic and not ns->save_all.

	* gfortran.fortran-torture/execute/save_1.f90: New test.
	* gfortran.dg/save_1.f90: New test.

--- gcc/fortran/symbol.c.jj	2005-09-19 22:45:54.000000000 +0200
+++ gcc/fortran/symbol.c	2005-09-26 08:54:36.000000000 +0200
@@ -2345,7 +2345,7 @@ gfc_is_var_automatic (gfc_symbol * sym)
   /* Check for non-constant length character variables.  */
   if (sym->ts.type == BT_CHARACTER
       && sym->ts.cl
-      && gfc_is_constant_expr (sym->ts.cl->length))
+      && !gfc_is_constant_expr (sym->ts.cl->length))
     return true;
   return false;
 }
@@ -2369,6 +2369,17 @@ save_symbol (gfc_symbol * sym)
   gfc_add_save (&sym->attr, sym->name, &sym->declared_at);
 }
 
+/* Given a symbol, mark it as SAVEd if it is allowed and not
+   already saved.  */
+
+static void
+maybe_save_symbol (gfc_symbol * sym)
+{
+  if (sym->attr.save)
+    return;
+  save_symbol (sym);
+}
+
 
 /* Mark those symbols which can be SAVEd as such.  */
 
@@ -2380,6 +2391,16 @@ gfc_save_all (gfc_namespace * ns)
 }
 
 
+/* Similarly, but only attempt to SAVE what hasn't been SAVEd already
+   explicitly.  */
+
+void
+gfc_no_automatic_save_all (gfc_namespace * ns)
+{
+  gfc_traverse_ns (ns, maybe_save_symbol);
+}
+
+
 #ifdef GFC_DEBUG
 /* Make sure that no changes to symbols are pending.  */
 
--- gcc/fortran/gfortran.h.jj	2005-09-19 22:45:54.000000000 +0200
+++ gcc/fortran/gfortran.h	2005-09-26 08:55:13.000000000 +0200
@@ -1699,6 +1699,7 @@ void gfc_traverse_symtree (gfc_symtree *
 void gfc_traverse_ns (gfc_namespace *, void (*)(gfc_symbol *));
 void gfc_traverse_user_op (gfc_namespace *, void (*)(gfc_user_op *));
 void gfc_save_all (gfc_namespace *);
+void gfc_no_automatic_save_all (gfc_namespace *);
 
 void gfc_symbol_state (void);
 
--- gcc/fortran/resolve.c.jj	2005-09-26 08:39:40.000000000 +0200
+++ gcc/fortran/resolve.c	2005-09-26 08:56:38.000000000 +0200
@@ -5107,8 +5107,10 @@ gfc_resolve (gfc_namespace * ns)
 
   gfc_traverse_ns (ns, resolve_values);
 
-  if (!gfc_option.flag_automatic || ns->save_all)
+  if (ns->save_all)
     gfc_save_all (ns);
+  else if (!gfc_option.flag_automatic)
+    gfc_no_automatic_save_all (ns);
 
   iter_stack = NULL;
   for (d = ns->data; d; d = d->next)
--- gcc/testsuite/gfortran.dg/save_1.f90.jj	2005-09-26 09:20:34.000000000 +0200
+++ gcc/testsuite/gfortran.dg/save_1.f90	2005-09-26 09:22:23.000000000 +0200
@@ -0,0 +1,30 @@
+! { dg-options "-O2 -fno-automatic" }
+      subroutine foo (b)
+	logical b
+	integer i, j
+	character*24 s
+	save i
+	if (b) then
+	  i = 26
+	  j = 131
+	  s = 'This is a test string'
+	else
+	  if (i .ne. 26 .or. j .ne. 131) call abort
+	  if (s .ne. 'This is a test string') call abort
+	end if
+      end subroutine foo
+      subroutine bar (s)
+	character*42 s
+	if (s .ne. '0123456789012345678901234567890123456') call abort
+	call foo (.false.)
+      end subroutine bar
+      subroutine baz
+	character*42 s
+	! Just clobber stack a little bit.
+	s = '0123456789012345678901234567890123456'
+	call bar (s)
+      end subroutine baz
+      call foo (.true.)
+      call baz
+      call foo (.false.)
+      end
--- gcc/testsuite/gfortran.fortran-torture/execute/save_1.f90.jj	2005-09-26 09:19:56.000000000 +0200
+++ gcc/testsuite/gfortran.fortran-torture/execute/save_1.f90	2005-09-26 09:21:36.000000000 +0200
@@ -0,0 +1,29 @@
+      subroutine foo (b)
+	logical b
+	integer i, j
+	character*24 s
+	save
+	if (b) then
+	  i = 26
+	  j = 131
+	  s = 'This is a test string'
+	else
+	  if (i .ne. 26 .or. j .ne. 131) call abort
+	  if (s .ne. 'This is a test string') call abort
+	end if
+      end subroutine foo
+      subroutine bar (s)
+	character*42 s
+	if (s .ne. '0123456789012345678901234567890123456') call abort
+	call foo (.false.)
+      end subroutine bar
+      subroutine baz
+	character*42 s
+	! Just clobber stack a little bit.
+	s = '0123456789012345678901234567890123456'
+	call bar (s)
+      end subroutine baz
+      call foo (.true.)
+      call baz
+      call foo (.false.)
+      end

	Jakub


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