This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix Fortran -fno-automatic and save_all (PR fortran/23677)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org, fortran at gcc dot gnu dot org
- Date: Mon, 26 Sep 2005 04:36:45 -0400
- Subject: [PATCH] Fix Fortran -fno-automatic and save_all (PR fortran/23677)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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