]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/20896 (ambiguous interface not detected)
authorPaul Thomas <pault@gcc.gnu.org>
Wed, 27 Dec 2006 13:46:47 +0000 (13:46 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Wed, 27 Dec 2006 13:46:47 +0000 (13:46 +0000)
2006-12-27  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/20896
* interface.c (check_sym_interfaces): Try to resolve interface
reference as a global symbol, if it is not a nodule procedure.
(compare_actual_formal): Remove call to gfc_find_symbol; if
the expression is already a variable it is locally declared
and this has precedence.
gfortran.h : Add prototype for resolve_global_procedure.
resolve.c (resolve_global_procedure): Remove static attribute
from function declaration.
(resolve_fl_procedure): Remove symtree declaration and the
redundant check for an ambiguous procedure.

PR fortran/25135
* module.c (load_generic_interfaces): If the symbol is present
and is not generic it is ambiguous.

2006-12-27  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/20896
* gfortran.dg/interface_10.f90: New test.
* gfortran.dg/dummy_procedure_1.f90: Add error for call s1(z),
since z is already, locally a variable.

PR fortran/25135
* gfortran.dg/generic_11.f90: New test.
* gfortran.dg/interface_7.f90: Remove name clash between module
name and procedure 'x' referenced in the interface.

From-SVN: r120218

gcc/fortran/ChangeLog
gcc/fortran/gfortran.h
gcc/fortran/interface.c
gcc/fortran/module.c
gcc/fortran/resolve.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/dummy_procedure_1.f90
gcc/testsuite/gfortran.dg/generic_11.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/interface_10.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/interface_7.f90

index c47a3b85cbe733cc9f4171bd21bd9d733fa3b897..49db7dcd17276a5c67e3b19ce969320c2805108f 100644 (file)
@@ -1,3 +1,21 @@
+2006-12-27  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/20896
+       * interface.c (check_sym_interfaces): Try to resolve interface
+       reference as a global symbol, if it is not a nodule procedure.
+       (compare_actual_formal): Remove call to gfc_find_symbol; if
+       the expression is already a variable it is locally declared
+       and this has precedence.
+       gfortran.h : Add prototype for resolve_global_procedure.
+       resolve.c (resolve_global_procedure): Remove static attribute
+       from function declaration.
+       (resolve_fl_procedure): Remove symtree declaration and the
+       redundant check for an ambiguous procedure.
+
+       PR fortran/25135
+       * module.c (load_generic_interfaces): If the symbol is present
+       and is not generic it is ambiguous.
+
 2006-12-22  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/25818
index 62862977eeb1d5f0a2aa500cc3f78d09d8100900..b477439ff64fb19fe923649302e0a8e92a247f05 100644 (file)
@@ -2032,6 +2032,7 @@ void gfc_free_statement (gfc_code *);
 void gfc_free_statements (gfc_code *);
 
 /* resolve.c */
+void resolve_global_procedure (gfc_symbol *, locus *, int);
 try gfc_resolve_expr (gfc_expr *);
 void gfc_resolve (gfc_namespace *);
 void gfc_resolve_blocks (gfc_code *, gfc_namespace *);
index 1a5485eaf71f9ceefe1c41a20b9d1ad3ac83b53d..8ec0b92bf1089961149d80e462acaae934add1bf 100644 (file)
@@ -1016,6 +1016,11 @@ check_sym_interfaces (gfc_symbol * sym)
   if (sym->ns != gfc_current_ns)
     return;
 
+  if (sym->attr.if_source == IFSRC_IFBODY
+       && sym->attr.flavor == FL_PROCEDURE
+       && !sym->attr.mod_proc)
+    resolve_global_procedure (sym, &sym->declared_at, sym->attr.subroutine);
+
   if (sym->generic != NULL)
     {
       sprintf (interface_name, "generic interface '%s'", sym->name);
@@ -1371,16 +1376,10 @@ compare_actual_formal (gfc_actual_arglist ** ap,
          && a->expr->expr_type == EXPR_VARIABLE
          && f->sym->attr.flavor == FL_PROCEDURE)
        {
-         gsym = gfc_find_gsymbol (gfc_gsym_root,
-                                  a->expr->symtree->n.sym->name);
-         if (gsym == NULL || (gsym->type != GSYM_FUNCTION
-               && gsym->type != GSYM_SUBROUTINE))
-           {
-             if (where)
-               gfc_error ("Expected a procedure for argument '%s' at %L",
-                          f->sym->name, &a->expr->where);
-             return 0;
-           }
+         if (where)
+           gfc_error ("Expected a procedure for argument '%s' at %L",
+                      f->sym->name, &a->expr->where);
+         return 0;
        }
 
       if (f->sym->attr.flavor == FL_PROCEDURE
index dc138d3e5cacc2596e8f865eca9fc8eb2d1c09c7..05056a5cb44154b29ae033248ddcc488df6eb20b 100644 (file)
@@ -3090,6 +3090,16 @@ load_generic_interfaces (void)
              sym->attr.generic = 1;
              sym->attr.use_assoc = 1;
            }
+         else
+           {
+             /* Unless sym is a generic interface, this reference
+                is ambiguous.  */
+             gfc_symtree *st;
+             p = p ? p : name;
+             st = gfc_find_symtree (gfc_current_ns->sym_root, p);
+             st->ambiguous = sym->attr.generic ? 0 : 1;
+           }
+
          if (i == 1)
            {
              mio_interface_rest (&sym->generic);
index eaa939debec6901ee29213fd2c666c89244c7bdc..9794446d169bdab7fee598aa0f826ae4b14ae6f8 100644 (file)
@@ -1156,7 +1156,7 @@ find_noncopying_intrinsics (gfc_symbol * fnsym, gfc_actual_arglist * actual)
    reference.  The corresponding code that is called in creating
    global entities is parse.c.  */
 
-static void
+void
 resolve_global_procedure (gfc_symbol *sym, locus *where, int sub)
 {
   gfc_gsymbol * gsym;
@@ -5560,7 +5560,6 @@ static try
 resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
 {
   gfc_formal_arglist *arg;
-  gfc_symtree *st;
 
   if (sym->attr.ambiguous_interfaces && !sym->attr.referenced)
     gfc_warning ("Although not referenced, '%s' at %L has ambiguous "
@@ -5570,16 +5569,6 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
        && resolve_fl_var_and_proc (sym, mp_flag) == FAILURE)
     return FAILURE;
 
-  st = gfc_find_symtree (gfc_current_ns->sym_root, sym->name);
-  if (st && st->ambiguous
-        && sym->attr.referenced
-        && !sym->attr.generic)
-    {
-      gfc_error ("Procedure %s at %L is ambiguous",
-                sym->name, &sym->declared_at);
-      return FAILURE;
-    }
-
   if (sym->ts.type == BT_CHARACTER)
     {
       gfc_charlen *cl = sym->ts.cl;
index 614ece93ee8da21d0a6c1e8a5bc98d33a06cfc06..9d0be233c1fbcf736ab2537301ee2c193fda8339 100644 (file)
@@ -1,3 +1,15 @@
+2006-12-27  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/20896
+       * gfortran.dg/interface_10.f90: New test.
+       * gfortran.dg/dummy_procedure_1.f90: Add error for call s1(z),
+       since z is already, locally a variable.
+
+       PR fortran/25135
+       * gfortran.dg/generic_11.f90: New test.
+       * gfortran.dg/interface_7.f90: Remove name clash between module
+       name and procedure 'x' referenced in the interface.
+
 2006-12-23  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        PR middle-end/7651
index 66aca21e3d03ef855accfc456c3f9bba5e79d157..6d681436125bea5e06b2fcb2bdcb0605e7cc085f 100644 (file)
@@ -37,7 +37,7 @@ end module m1
   call s1(w) ! { dg-error "not allowed as an actual argument" }
   call s1(x) ! explicit interface
   call s1(y) ! declared external
-  call s1(z) ! already compiled
+  call s1(z) ! { dg-error "Expected a procedure for argument" }
 contains
   integer function w()
     w = 1
diff --git a/gcc/testsuite/gfortran.dg/generic_11.f90 b/gcc/testsuite/gfortran.dg/generic_11.f90
new file mode 100644 (file)
index 0000000..7547a43
--- /dev/null
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! Test the fix for PR25135 in which the ambiguity between subroutine
+! foo in m_foo and interface foo in m_bar was not recognised.
+!
+!Contributed by Yusuke IGUCHI <iguchi@coral.t.u-tokyo.ac.jp>
+!
+module m_foo
+contains
+  subroutine foo
+    print *, "foo"
+  end subroutine
+end module
+
+module m_bar
+  interface foo
+    module procedure bar
+  end interface
+contains
+  subroutine bar
+    print *, "bar"
+  end subroutine
+end module
+
+use m_foo
+use m_bar
+
+call foo ! { dg-error "is an ambiguous reference" } 
+end
+! { dg-final { cleanup-modules "m_foo m_bar" } }
+
+
diff --git a/gcc/testsuite/gfortran.dg/interface_10.f90 b/gcc/testsuite/gfortran.dg/interface_10.f90
new file mode 100644 (file)
index 0000000..4dab96a
--- /dev/null
@@ -0,0 +1,33 @@
+! { dg-do compile }
+! Test the fix for PR20896 in which the ambiguous use
+! of p was not detected.
+!
+! Contributed by Joost VandeVondele <jv244@cam.ac.uk>
+!
+  INTERFACE g
+    SUBROUTINE s1(p) ! { dg-error "is already being used" }
+      INTERFACE
+        SUBROUTINE p
+        END
+      END INTERFACE
+    END
+    SUBROUTINE s2(p) ! { dg-error "Global name" }
+      INTERFACE
+        REAL FUNCTION p()
+        END
+      END INTERFACE
+    END
+  END INTERFACE
+
+      INTERFACE
+        REAL FUNCTION x()
+        END
+      END INTERFACE
+      INTERFACE
+        SUBROUTINE y
+        END
+      END INTERFACE
+  call g (x)
+  call g (y)
+  END
+
index 545211aec367a49e7dbe907c5ba7ad4d1ad0409c..9f59b49721461ffce92e80947b930f39b43d5774 100644 (file)
@@ -6,7 +6,7 @@
 ! standard explicitly does not require recursion into the formal
 ! arguments of procedures that themselves are interface arguments.
 !
-module x
+module xx
   INTERFACE BAD9
     SUBROUTINE S9A(X)
       REAL :: X
@@ -27,6 +27,6 @@ module x
       END INTERFACE
     END SUBROUTINE S9C  ! { dg-error "Ambiguous interfaces" }
   END INTERFACE BAD9
-end module x
+end module xx
 
-! { dg-final { cleanup-modules "x" } }
+! { dg-final { cleanup-modules "xx" } }