re PR fortran/31474 (ENTRY & procedural pointer: insert_bbt(): Duplicate key found!)
authorPaul Thomas <pault@gcc.gnu.org>
Fri, 11 May 2007 06:19:57 +0000 (06:19 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Fri, 11 May 2007 06:19:57 +0000 (06:19 +0000)
2007-05-11  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/31474
* decl.c (get_proc_name): If an entry has already been declared
as a module procedure, pick up the symbol and the symtree and
use them for the entry.

2007-05-11  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/31474
* gfortran.dg/entry_10.f90: New test.

From-SVN: r124613

gcc/fortran/ChangeLog
gcc/fortran/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/entry_10.f90 [new file with mode: 0644]

index 3613745..342864b 100644 (file)
@@ -1,3 +1,10 @@
+2007-05-11  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/31474
+       * decl.c (get_proc_name): If an entry has already been declared
+       as a module procedure, pick up the symbol and the symtree and
+       use them for the entry.
+
 2007-05-08  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/31630
index 0071f90..9eeacc0 100644 (file)
@@ -671,7 +671,12 @@ get_proc_name (const char *name, gfc_symbol **result, bool module_fcn_entry)
      space is set to point to the master function, so that the fake
      result mechanism can work.  */
   if (module_fcn_entry)
-    rc = gfc_get_symbol (name, NULL, result);
+    {
+      /* Present if entry is declared to be a module procedure.  */
+      rc = gfc_find_symbol (name, gfc_current_ns->parent, 0, result);
+      if (*result == NULL)
+       rc = gfc_get_symbol (name, NULL, result);
+    }
   else
     rc = gfc_get_symbol (name, gfc_current_ns->parent, result);
 
@@ -712,7 +717,12 @@ get_proc_name (const char *name, gfc_symbol **result, bool module_fcn_entry)
   /* Module function entries will already have a symtree in
      the current namespace but will need one at module level.  */
   if (module_fcn_entry)
-    st = gfc_new_symtree (&gfc_current_ns->parent->sym_root, name);
+    {
+      /* Present if entry is declared to be a module procedure.  */
+      rc = gfc_find_sym_tree (name, gfc_current_ns->parent, 0, &st);
+      if (st == NULL)
+       st = gfc_new_symtree (&gfc_current_ns->parent->sym_root, name);
+    }
   else
     st = gfc_new_symtree (&gfc_current_ns->sym_root, name);
 
@@ -722,10 +732,11 @@ get_proc_name (const char *name, gfc_symbol **result, bool module_fcn_entry)
   /* See if the procedure should be a module procedure */
 
   if (((sym->ns->proc_name != NULL
-       && sym->ns->proc_name->attr.flavor == FL_MODULE
-       && sym->attr.proc != PROC_MODULE) || module_fcn_entry)
-       && gfc_add_procedure (&sym->attr, PROC_MODULE,
-                            sym->name, NULL) == FAILURE)
+               && sym->ns->proc_name->attr.flavor == FL_MODULE
+               && sym->attr.proc != PROC_MODULE)
+           || (module_fcn_entry && sym->attr.proc != PROC_MODULE))
+       && gfc_add_procedure (&sym->attr, PROC_MODULE,
+                             sym->name, NULL) == FAILURE)
     rc = 2;
 
   return rc;
index c0e3d1e..641c050 100644 (file)
@@ -1,3 +1,8 @@
+2007-05-11  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/31474
+       * gfortran.dg/entry_10.f90: New test.
+
 2007-05-10  Zdenek Dvorak  <dvorakz@suse.cz>
 
        PR tree-optimization/31885
diff --git a/gcc/testsuite/gfortran.dg/entry_10.f90 b/gcc/testsuite/gfortran.dg/entry_10.f90
new file mode 100644 (file)
index 0000000..154d44e
--- /dev/null
@@ -0,0 +1,36 @@
+! { dg-do run }
+! Test fix for PR31474, in which the use of ENTRYs as module
+! procedures in a generic interface would cause an internal error.
+!
+! Contributed by Michael Richmond <michael.a.richmond@nasa.gov>
+!
+module a
+  interface b
+    module procedure c, d
+  end interface
+contains
+  real function d (i)
+    real c, i
+    integer j
+    d = 1.0
+    return
+  entry c (j)
+    d = 2.0
+  end function
+  real function e (i)
+    real f, i
+    integer j
+    e = 3.0
+    return
+  entry f (j)
+    e = 4.0
+  end function
+end module
+
+  use a
+  if (b (1.0) .ne. 1.0) call abort ()
+  if (b (1  ) .ne. 2.0) call abort ()
+  if (e (1.0) .ne. 3.0) call abort ()
+  if (f (1  ) .ne. 4.0) call abort ()
+end
+! { dg-final { cleanup-modules "a" } }