]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/29464 ([4.1 only] problem with duplicate USE, ONLY of procedure in...
authorPaul Thomas <pault@gcc.gnu.org>
Sat, 9 Dec 2006 20:52:27 +0000 (20:52 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Sat, 9 Dec 2006 20:52:27 +0000 (20:52 +0000)
2006-11-25  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/29464
* module.c (load_generic_interfaces): Add symbols for all the
local names of an interface.  Share the interface amongst the
symbols.
* gfortran.h : Add generic_copy to symbol_attribute.
* symbol.c (free_symbol): Only free interface if generic_copy
is not set.

2006-11-25  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/29464
* gfortran.dg/module_interface_2.f90: New test.

From-SVN: r119696

gcc/fortran/ChangeLog
gcc/fortran/gfortran.h
gcc/fortran/module.c
gcc/fortran/symbol.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/module_interface_2.f90 [new file with mode: 0644]

index 1a6b28afcde204d54f3faaca00825e88d2e4ca17..f3602064f96e1bbb2ecc01f11bd269af738af70c 100644 (file)
@@ -1,3 +1,13 @@
+2006-12-09  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/29464
+       * module.c (load_generic_interfaces): Add symbols for all the
+       local names of an interface.  Share the interface amongst the
+       symbols.
+       * gfortran.h : Add generic_copy to symbol_attribute.
+       * symbol.c (free_symbol): Only free interface if generic_copy
+       is not set.
+
 2006-12-09  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/29941
index 3a3b680f88f99b98032e4c34bd20eab3e4e20d31..5e4b322aebf03904f10e191d9aac7cc9c3de847d 100644 (file)
@@ -486,7 +486,7 @@ typedef struct
     use_assoc:1;               /* Symbol has been use-associated.  */
 
   unsigned in_namelist:1, in_common:1, in_equivalence:1;
-  unsigned function:1, subroutine:1, generic:1;
+  unsigned function:1, subroutine:1, generic:1, generic_copy:1;
   unsigned implicit_type:1;    /* Type defined via implicit rules.  */
   unsigned untyped:1;           /* No implicit type could be found.  */
 
index 6956fc980c5595b1fd9c2d9ad4b1810a00dcd1da..7c9c2b1ab3cbf1933c377e313829931603c9c918 100644 (file)
@@ -3024,6 +3024,8 @@ load_generic_interfaces (void)
   const char *p;
   char name[GFC_MAX_SYMBOL_LEN + 1], module[GFC_MAX_SYMBOL_LEN + 1];
   gfc_symbol *sym;
+  gfc_interface *generic = NULL;
+  int n, i;
 
   mio_lparen ();
 
@@ -3034,25 +3036,39 @@ load_generic_interfaces (void)
       mio_internal_string (name);
       mio_internal_string (module);
 
-      /* Decide if we need to load this one or not.  */
-      p = find_use_name (name);
+      n = number_use_names (name);
+      n = n ? n : 1;
 
-      if (p == NULL || gfc_find_symbol (p, NULL, 0, &sym))
+      for (i = 1; i <= n; i++)
        {
-         while (parse_atom () != ATOM_RPAREN);
-         continue;
-       }
+         /* Decide if we need to load this one or not.  */
+         p = find_use_name_n (name, &i);
 
-      if (sym == NULL)
-       {
-         gfc_get_symbol (p, NULL, &sym);
+         if (p == NULL || gfc_find_symbol (p, NULL, 0, &sym))
+           {
+             while (parse_atom () != ATOM_RPAREN);
+               continue;
+           }
 
-         sym->attr.flavor = FL_PROCEDURE;
-         sym->attr.generic = 1;
-         sym->attr.use_assoc = 1;
-       }
+         if (sym == NULL)
+           {
+             gfc_get_symbol (p, NULL, &sym);
 
-      mio_interface_rest (&sym->generic);
+             sym->attr.flavor = FL_PROCEDURE;
+             sym->attr.generic = 1;
+             sym->attr.use_assoc = 1;
+           }
+         if (i == 1)
+           {
+             mio_interface_rest (&sym->generic);
+             generic = sym->generic;
+           }
+         else
+           {
+             sym->generic = generic;
+             sym->attr.generic_copy = 1;
+           }
+       }
     }
 
   mio_rparen ();
index 228567bd5e8ec29692dacafe300a35032595d4a6..7cb5e762de50be0f8115c61ef45d181eda3aadd5 100644 (file)
@@ -1971,7 +1971,8 @@ gfc_free_symbol (gfc_symbol * sym)
 
   gfc_free_namespace (sym->formal_ns);
 
-  gfc_free_interface (sym->generic);
+  if (!sym->attr.generic_copy)
+    gfc_free_interface (sym->generic);
 
   gfc_free_formal_arglist (sym->formal);
 
index 761d53bb66053fe767606011ac7bc9d2bfbfb392..5204470816a20fa2518585f7944b3770c7d11df1 100644 (file)
@@ -1,3 +1,8 @@
+2006-12-09  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/29464
+       * gfortran.dg/module_interface_2.f90: New test.
+
 2006-12-09  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/29941
diff --git a/gcc/testsuite/gfortran.dg/module_interface_2.f90 b/gcc/testsuite/gfortran.dg/module_interface_2.f90
new file mode 100644 (file)
index 0000000..1f9fde8
--- /dev/null
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! Tests the fix for PR29464, in which the second USE of the generic
+! interface caused an error.
+!
+! Contributed by Vivek Rao <vivekrao4@yahoo.com>
+!
+module foo_mod
+  implicit none
+  interface twice
+     module procedure twice_real
+  end interface twice
+contains
+  real function twice_real(x)
+    real :: x
+    twice_real = 2*x
+  end function twice_real
+end module foo_mod
+
+  subroutine foobar ()
+    use foo_mod, only: twice, twice
+    print *, twice (99.0)
+  end subroutine foobar
+
+  program xfoo
+  use foo_mod, only: two => twice, dbl => twice
+  implicit none
+  call foobar ()
+  print *, two (2.3)
+  print *, dbl (2.3)
+end program xfoo
+! { dg-final { cleanup-modules "foo_mod" } }