2007-11-15 Tobias Burnus <burnus@net-b.de>
authorburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 15 Nov 2007 15:12:03 +0000 (15:12 +0000)
committerburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 15 Nov 2007 15:12:03 +0000 (15:12 +0000)
        PR fortran/33917
        * decl.c (match_procedure_decl): Pre-resolve interface.
        * resolve.c (resolve_symbol): Reject interfaces later
        declared in procedure statements.

2007-11-15  Tobias Burnus  <burnus@net-b.de>

        PR fortran/33917
        * gfortran.dg/proc_decl_11.f90: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130202 138bc75d-0d04-0410-961f-82ee72b054a4

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

index a38d4ad..5411776 100644 (file)
@@ -1,3 +1,10 @@
+2007-11-15  Tobias Burnus  <burnus@net-b.de>
+
+       PR fortran/33917
+       * decl.c (match_procedure_decl): Pre-resolve interface.
+       * resolve.c (resolve_symbol): Reject interfaces later
+       declared in procedure statements.
+
 2007-11-13  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/33162
index 29b02ea..be197bc 100644 (file)
@@ -3946,6 +3946,12 @@ match_procedure_decl (void)
   /* Various interface checks.  */
   if (proc_if)
     {
+      /* Resolve interface if possible. That way, attr.procedure is only set
+        if it is declared by a later procedure-declaration-stmt, which is
+        invalid per C1212.  */
+      while (proc_if->interface)
+       proc_if = proc_if->interface;
+
       if (proc_if->generic)
        {
          gfc_error ("Interface '%s' at %C may not be generic", proc_if->name);
index 3f3ef03..586d601 100644 (file)
@@ -7615,8 +7615,10 @@ resolve_symbol (gfc_symbol *sym)
   if (sym->attr.procedure && sym->interface
       && sym->attr.if_source != IFSRC_DECL)
     {
-      while (sym->interface->interface)
-       sym->interface = sym->interface->interface;
+      if (sym->interface->attr.procedure)
+       gfc_error ("Interface '%s', used by procedure '%s' at %L, is declared "
+                  "in a later PROCEDURE statement", sym->interface->name,
+                  sym->name,&sym->declared_at);
 
       /* Get the attributes from the interface (now resolved).  */
       if (sym->interface->attr.if_source || sym->interface->attr.intrinsic)
index d937f4f..b3e26c0 100644 (file)
@@ -1,3 +1,8 @@
+2007-11-15  Tobias Burnus  <burnus@net-b.de>
+
+       PR fortran/33917
+       * gfortran.dg/proc_decl_11.f90: New.
+
 2007-11-15  Ben Elliston  <bje@au.ibm.com>
 
        * gcc.target/spu/compare-dp.c: New test.
diff --git a/gcc/testsuite/gfortran.dg/proc_decl_11.f90 b/gcc/testsuite/gfortran.dg/proc_decl_11.f90
new file mode 100644 (file)
index 0000000..74c0680
--- /dev/null
@@ -0,0 +1,34 @@
+! { dg-do compile }
+! PR fortran/33917
+!
+! Depending, in which order the symbol tree
+! was walked in resolve, gfortran resolved
+! p6 before p4; thus there was no explicit
+! interface available for p4 and an error
+! was printed. (This is a variant of proc_decl_2.f90)
+!
+! Additionally, the following contrain was not honoured:
+! "C1212 (R1215) [...] If name is declared by a procedure-declaration-stmt
+! it shall be previously declared." ("name" = interface-name)
+!
+program s
+  implicit none
+  procedure() :: q2
+  procedure() :: q3
+  procedure() :: q5
+  procedure(sub) :: p4
+  procedure(p4) :: p6
+contains
+  subroutine sub
+  end subroutine
+end program s
+
+subroutine test
+  implicit none
+  abstract interface
+    subroutine sub()
+    end subroutine sub
+  end interface
+  procedure(p4) :: p6 ! { dg-error "declared in a later PROCEDURE statement" }
+  procedure(sub) :: p4
+end subroutine test