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 EQUIVALENCE vs. SAVE (PR fortran/18518)


Hi!

I couldn't find details on SAVE and EQUIVALENCE coexistence in the standard,
but g77 certainly saved equivalences if any of the equivalenced variables
were saved.
Is this ok for HEAD/4.0 (tested on x86_64-linux)?

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

	PR fortran/18518
	* trans-common.c (build_equiv_decl): Add IS_SAVED argument.
	If it is true, set TREE_STATIC on the decl.
	(create_common): If any symbol in equivalence has SAVE attribute,
	pass true as last argument to build_equiv_decl.

	* gfortran.fortran-torture/execute/save_2.f90: New decl.

--- fortran/trans-common.c.jj	2005-09-09 09:49:39.000000000 +0200
+++ fortran/trans-common.c	2005-09-27 21:51:53.000000000 +0200
@@ -268,7 +268,7 @@ build_field (segment_info *h, tree union
 /* Get storage for local equivalence.  */
 
 static tree
-build_equiv_decl (tree union_type, bool is_init)
+build_equiv_decl (tree union_type, bool is_init, bool is_saved)
 {
   tree decl;
   char name[15];
@@ -286,7 +286,8 @@ build_equiv_decl (tree union_type, bool 
   DECL_ARTIFICIAL (decl) = 1;
   DECL_IGNORED_P (decl) = 1;
 
-  if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl)))
+  if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
+      || is_saved)
     TREE_STATIC (decl) = 1;
 
   TREE_ADDRESSABLE (decl) = 1;
@@ -385,6 +386,7 @@ create_common (gfc_common_head *com, seg
   record_layout_info rli;
   tree decl;
   bool is_init = false;
+  bool is_saved = false;
 
   /* Declare the variables inside the common block.
      If the current common block contains any equivalence object, then
@@ -410,13 +412,17 @@ create_common (gfc_common_head *com, seg
       /* Has initial value.  */
       if (s->sym->value)
         is_init = true;
+
+      /* Has SAVE attribute.  */
+      if (s->sym->attr.save)
+        is_saved = true;
     }
   finish_record_layout (rli, true);
 
   if (com)
     decl = build_common_decl (com, union_type, is_init);
   else
-    decl = build_equiv_decl (union_type, is_init);
+    decl = build_equiv_decl (union_type, is_init, is_saved);
 
   if (is_init)
     {
--- testsuite/gfortran.fortran-torture/execute/save_2.f90.jj	2005-09-27 22:02:03.000000000 +0200
+++ testsuite/gfortran.fortran-torture/execute/save_2.f90	2005-09-27 22:01:48.000000000 +0200
@@ -0,0 +1,23 @@
+! PR fortran/18518
+      program main
+	call foo
+	call bar
+	call foo
+      end program main
+
+      subroutine foo
+	integer i,g,h
+	data i/0/
+	equivalence (g,h)
+	save g
+	if (i == 0) then
+	   i = 1
+	   h = 12345
+	end if
+	if (h .ne. 12345) call abort
+      end subroutine foo
+
+      subroutine bar
+	integer a(10)
+	a = 34
+      end subroutine bar

	Jakub


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