This is the mail archive of the gcc-bugs@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]

[Bug fortran/32103] Module with equivalence draws "unsatisfied reference"



------- Comment #4 from pault at gcc dot gnu dot org  2007-05-29 10:39 -------
The patch below works and regtests OK.  I am trying to devise a safe method of
gettting rid of the redundant symbols if none of the equivalence members is
USEd.  If I cannot see something by tonight, I will submit anyway.

Paul

Index: gcc/fortran/module.c
===================================================================
--- gcc/fortran/module.c        (révision 125056)
+++ gcc/fortran/module.c        (copie de travail)
@@ -189,7 +189,7 @@ static gfc_use_rename *gfc_rename_list;
 static pointer_info *pi_root;
 static int symbol_number;      /* Counter for assigning symbol numbers */

-/* Tells mio_expr_ref not to load unused equivalence members.  */
+/* Tells mio_expr_ref to make symbols for unused equivalence members.  */
 static bool in_load_equiv;


@@ -1501,10 +1501,10 @@ mio_internal_string (char *string)
 typedef enum
 { AB_ALLOCATABLE, AB_DIMENSION, AB_EXTERNAL, AB_INTRINSIC, AB_OPTIONAL,
   AB_POINTER, AB_SAVE, AB_TARGET, AB_DUMMY, AB_RESULT, AB_DATA,
-  AB_IN_NAMELIST, AB_IN_COMMON, AB_FUNCTION, AB_SUBROUTINE, AB_SEQUENCE,
-  AB_ELEMENTAL, AB_PURE, AB_RECURSIVE, AB_GENERIC, AB_ALWAYS_EXPLICIT,
-  AB_CRAY_POINTER, AB_CRAY_POINTEE, AB_THREADPRIVATE, AB_ALLOC_COMP,
-  AB_VALUE, AB_VOLATILE, AB_PROTECTED
+  AB_IN_NAMELIST, AB_IN_EQUIVALENCE, AB_IN_COMMON, AB_FUNCTION,
+  AB_SUBROUTINE, AB_SEQUENCE, AB_ELEMENTAL, AB_PURE, AB_RECURSIVE,
+  AB_GENERIC, AB_ALWAYS_EXPLICIT, AB_CRAY_POINTER, AB_CRAY_POINTEE,
+  AB_THREADPRIVATE, AB_ALLOC_COMP, AB_VALUE, AB_VOLATILE, AB_PROTECTED
 }
 ab_attribute;

@@ -1525,6 +1525,7 @@ static const mstring attr_bits[] =
     minit ("RESULT", AB_RESULT),
     minit ("DATA", AB_DATA),
     minit ("IN_NAMELIST", AB_IN_NAMELIST),
+    minit ("IN_EQUIVALENCE", AB_IN_EQUIVALENCE),
     minit ("IN_COMMON", AB_IN_COMMON),
     minit ("FUNCTION", AB_FUNCTION),
     minit ("SUBROUTINE", AB_SUBROUTINE),
@@ -1610,6 +1611,8 @@ mio_symbol_attribute (symbol_attribute *
        MIO_NAME (ab_attribute) (AB_DATA, attr_bits);
       if (attr->in_namelist)
        MIO_NAME (ab_attribute) (AB_IN_NAMELIST, attr_bits);
+      if (attr->in_equivalence)
+       MIO_NAME (ab_attribute) (AB_IN_EQUIVALENCE, attr_bits);
       if (attr->in_common)
        MIO_NAME (ab_attribute) (AB_IN_COMMON, attr_bits);

@@ -1700,6 +1703,9 @@ mio_symbol_attribute (symbol_attribute *
            case AB_IN_NAMELIST:
              attr->in_namelist = 1;
              break;
+           case AB_IN_EQUIVALENCE:
+             attr->in_equivalence = 1;
+             break;
            case AB_IN_COMMON:
              attr->in_common = 1;
              break;
@@ -2234,9 +2240,25 @@ mio_symtree_ref (gfc_symtree **stp)
       require_atom (ATOM_INTEGER);
       p = get_integer (atom_int);

-      /* An unused equivalence member; bail out.  */
+      /* An unused equivalence member; make a symbol and a symtree
+        for it.  */
       if (in_load_equiv && p->u.rsym.symtree == NULL)
-       return;
+       {
+         /* Since this is not used, it must have a unique name.  */
+         p->u.rsym.symtree = get_unique_symtree (gfc_current_ns);
+
+         /* Make the symbol.  */
+         if (p->u.rsym.sym == NULL)
+           {
+             p->u.rsym.sym = gfc_new_symbol (p->u.rsym.true_name,
+                                             gfc_current_ns);
+             p->u.rsym.sym->module = gfc_get_string (p->u.rsym.module);
+           }
+
+         p->u.rsym.symtree->n.sym = p->u.rsym.sym;
+         p->u.rsym.symtree->n.sym->refs++;
+         p->u.rsym.referenced = 1;
+       }

       if (p->type == P_UNKNOWN)
        p->type = P_SYMBOL;
@@ -3206,13 +3228,13 @@ load_equiv (void)
        mio_expr (&tail->expr);
       }

-    /* Unused variables have no symtree.  */
-    unused = false;
+    /* Unused equivalence members have a unique name.  */
+    unused = true;
     for (eq = head; eq; eq = eq->eq)
       {
-       if (!eq->expr->symtree)
+       if (!check_unique_name (eq->expr->symtree->name))
          {
-           unused = true;
+           unused = false;
            break;
          }
       }
Index: gcc/testsuite/gfortran.dg/module_equivalence_3.f90
===================================================================
--- gcc/testsuite/gfortran.dg/module_equivalence_3.f90  (révision 0)
+++ gcc/testsuite/gfortran.dg/module_equivalence_3.f90  (révision 0)
@@ -0,0 +1,38 @@
+! { dg-do run }
+! This checks the fix for PR32103 in which not using one member
+! of an equivalence group would cause all memory of the equivalence
+! to be lost and subsequent incorrect referencing of the remaining
+! members. 
+!
+! Contributed by Toon Moene <toon@moene.indiv.nluug.nl> 
+!
+module aap
+   real :: a(5) = (/1.0,2.0,3.0,4.0,5.0/) 
+   real :: b(3)
+   real :: d(5) = (/1.0,2.0,3.0,4.0,5.0/) 
+   equivalence (a(3),b(1))
+end module aap
+
+  use aap, only : b
+  call foo
+  call bar
+  call foobar
+contains
+  subroutine foo
+    use aap, only : c=>b
+    if (any(c .ne. b)) call abort ()
+  end subroutine
+  subroutine bar
+    use aap, only : a
+    if (any(a(3:5) .ne. b)) call abort ()
+  end subroutine
+
+! Make sure that bad things do not happen if we do not USE a or b.
+
+  subroutine foobar
+    use aap, only : d
+    if (any(d(3:5) .ne. b)) call abort ()
+  end subroutine
+end
+
+! { dg-final { cleanup-modules "aap" } }


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32103


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