re PR fortran/36325 (specific or generic INTERFACE implies the EXTERNAL attribute)
authorJanus Weil <janus@gcc.gnu.org>
Wed, 28 May 2008 21:27:56 +0000 (23:27 +0200)
committerJanus Weil <janus@gcc.gnu.org>
Wed, 28 May 2008 21:27:56 +0000 (23:27 +0200)
2008-05-28  Janus Weil  <janus@gcc.gnu.org>

PR fortran/36325
PR fortran/35830
* interface.c (gfc_procedure_use): Enable argument checking for
external procedures with explicit interface.
* symbol.c (check_conflict): Fix conflict checking for externals.
(copy_formal_args): Fix handling of arrays.
* resolve.c (resolve_specific_f0, resolve_specific_s0): Fix handling
of intrinsics.
* parse.c (parse_interface): Non-abstract INTERFACE statement implies
EXTERNAL attribute.

2008-05-28  Janus Weil  <janus@gcc.gnu.org>

PR fortran/36325
PR fortran/35830
* gfortran.dg/interface_23.f90: New.
* gfortran.dg/gomp/reduction3.f90: Fixed invalid code.
* gfortran.dg/proc_decl_12.f90: New:
* gfortran.dg/external_procedures_1.f90: Fixed error message.

From-SVN: r136130

gcc/fortran/ChangeLog
gcc/fortran/interface.c
gcc/fortran/parse.c
gcc/fortran/resolve.c
gcc/fortran/symbol.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/external_procedures_1.f90
gcc/testsuite/gfortran.dg/gomp/reduction3.f90
gcc/testsuite/gfortran.dg/interface_23.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/proc_decl_12.f90 [new file with mode: 0644]

index 1995f6ac16145b1c6938aeaeca7d22942429d307..cf05afcf665e3ef42abfcacec1247b17a44cc7e5 100644 (file)
@@ -1,3 +1,16 @@
+2008-05-28  Janus Weil  <janus@gcc.gnu.org>
+
+       PR fortran/36325
+       PR fortran/35830
+       * interface.c (gfc_procedure_use): Enable argument checking for
+       external procedures with explicit interface.
+       * symbol.c (check_conflict): Fix conflict checking for externals.
+       (copy_formal_args): Fix handling of arrays.
+       * resolve.c (resolve_specific_f0, resolve_specific_s0): Fix handling
+       of intrinsics.
+       * parse.c (parse_interface): Non-abstract INTERFACE statement implies
+       EXTERNAL attribute.
+
 2008-05-28  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
        PR fortran/36319
index f70cedba949c460d5f604639e710c77d4c026d02..f2ad4f6734e62741194cc992ddd8ffd284327465 100644 (file)
@@ -2421,8 +2421,7 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
        }
     }
 
-  if (sym->attr.external
-      || sym->attr.if_source == IFSRC_UNKNOWN)
+  if (sym->attr.if_source == IFSRC_UNKNOWN)
     {
       gfc_actual_arglist *a;
       for (a = *ap; a; a = a->next)
index dd072feb30e5b340eb3817c492e0863f8ecaa328..b7e63919e8ecb78ca829a18dfc8033c2833fef1a 100644 (file)
@@ -1917,12 +1917,28 @@ loop:
       new_state = COMP_SUBROUTINE;
       gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY,
                                  gfc_new_block->formal, NULL);
+      if (current_interface.type != INTERFACE_ABSTRACT &&
+        !gfc_new_block->attr.dummy &&
+        gfc_add_external (&gfc_new_block->attr, &gfc_current_locus) == FAILURE)
+       {
+         reject_statement ();
+         gfc_free_namespace (gfc_current_ns);
+         goto loop;
+       }
       break;
 
     case ST_FUNCTION:
       new_state = COMP_FUNCTION;
       gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY,
                                  gfc_new_block->formal, NULL);
+      if (current_interface.type != INTERFACE_ABSTRACT &&
+        !gfc_new_block->attr.dummy &&
+        gfc_add_external (&gfc_new_block->attr, &gfc_current_locus) == FAILURE)
+       {
+         reject_statement ();
+         gfc_free_namespace (gfc_current_ns);
+         goto loop;
+       }
       break;
 
     case ST_PROCEDURE:
index c3354a97d37b0d4893aac9359912a9d0d516b241..8044990b7dda40afda7c53770a76c2d9f096f3bb 100644 (file)
@@ -1571,7 +1571,8 @@ resolve_specific_f0 (gfc_symbol *sym, gfc_expr *expr)
       /* Existance of isym should be checked already.  */
       gcc_assert (isym);
 
-      sym->ts = isym->ts;
+      sym->ts.type = isym->ts.type;
+      sym->ts.kind = isym->ts.kind;
       sym->attr.function = 1;
       sym->attr.proc = PROC_EXTERNAL;
       goto found;
@@ -2646,8 +2647,9 @@ resolve_specific_s0 (gfc_code *c, gfc_symbol *sym)
       /* Existance of isym should be checked already.  */
       gcc_assert (isym);
 
-      sym->ts = isym->ts;
-      sym->attr.function = 1;
+      sym->ts.type = isym->ts.type;
+      sym->ts.kind = isym->ts.kind;
+      sym->attr.subroutine = 1;
       goto found;
     }
 
index 431b6513ce0e58a7b44aa2b566abe757c6efa908..e98a19c57fa6ecbf6414211aefb23ab2c59a5274 100644 (file)
@@ -434,12 +434,14 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
 
   conf (target, external);
   conf (target, intrinsic);
-  conf (external, dimension);   /* See Fortran 95's R504.  */
+
+  if (!attr->if_source)
+    conf (external, dimension);   /* See Fortran 95's R504.  */
 
   conf (external, intrinsic);
   conf (entry, intrinsic);
 
-  if ((attr->if_source && !attr->procedure) || attr->contained)
+  if ((attr->if_source == IFSRC_DECL && !attr->procedure) || attr->contained)
     {
       conf (external, subroutine);
       conf (external, function);
@@ -3664,6 +3666,7 @@ copy_formal_args (gfc_symbol *dest, gfc_symbol *src)
       /* May need to copy more info for the symbol.  */
       formal_arg->sym->attr = curr_arg->sym->attr;
       formal_arg->sym->ts = curr_arg->sym->ts;
+      formal_arg->sym->as = gfc_copy_array_spec (curr_arg->sym->as);
 
       /* If this isn't the first arg, set up the next ptr.  For the
         last arg built, the formal_arg->next will never get set to
index 1a33d2e1467908048ef3514b95d08936f5f9080e..c28d1fc3eca72de5aa120033aae4a767fe06cb38 100644 (file)
@@ -1,3 +1,12 @@
+2008-05-28  Janus Weil  <janus@gcc.gnu.org>
+
+       PR fortran/36325
+       PR fortran/35830
+       * gfortran.dg/interface_23.f90: New.
+       * gfortran.dg/gomp/reduction3.f90: Fixed invalid code.
+       * gfortran.dg/proc_decl_12.f90: New:
+       * gfortran.dg/external_procedures_1.f90: Fixed error message.
+       
 2008-05-28  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
        PR fortran/36319
index 95d0212353e6cddb08bda7ab02c741c7aa6dc28f..6e833be16e2eb2ed86af42ff5c8f86b73371602e 100644 (file)
@@ -24,7 +24,7 @@ program main
   interface
     function ext1 (y)
       real ext1, y
-      external ext1  ! { dg-error "EXTERNAL attribute conflicts with FUNCTION" }
+      external ext1  ! { dg-error "Duplicate EXTERNAL attribute" }
     end function ext1
   end interface
   inval = 1.0
@@ -38,4 +38,4 @@ contains
     inv = y * y * y
   end function inv
 end program main
-\r
+
index abd6d04415d23572ed4360c75a807db8bb19c549..0272a7415960e7cee6fb0031edf2fccc07dfbc2e 100644 (file)
@@ -33,11 +33,6 @@ subroutine f2
 end subroutine f2
 subroutine f3
   integer :: i
-  interface
-    function ior (a, b)
-      integer :: ior, a, b
-    end function
-  end interface
   intrinsic ior
   i = 6
 !$omp parallel reduction (ior:i)
diff --git a/gcc/testsuite/gfortran.dg/interface_23.f90 b/gcc/testsuite/gfortran.dg/interface_23.f90
new file mode 100644 (file)
index 0000000..60b6e79
--- /dev/null
@@ -0,0 +1,35 @@
+! { dg-do compile }
+!
+! This tests the fix for PR36325, which corrected for the fact that a
+! specific or generic INTERFACE statement implies the EXTERNAL attibute.
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+module a
+  interface
+    subroutine foo
+    end subroutine
+  end interface
+  external foo  ! { dg-error "Duplicate EXTERNAL attribute" }
+end module
+
+module b
+  interface
+    function sin (x)
+      real :: sin, x
+    end function
+  end interface
+  intrinsic sin  ! { dg-error "EXTERNAL attribute conflicts with INTRINSIC attribute" }
+end module
+
+! argument checking was not done for external procedures with explicit interface
+program c
+  interface
+    subroutine bar(x)
+      real :: x
+    end subroutine
+  end interface
+  call bar()  ! { dg-error "Missing actual argument" }
+end program
+
+! { dg-final { cleanup-modules "a b" } }
diff --git a/gcc/testsuite/gfortran.dg/proc_decl_12.f90 b/gcc/testsuite/gfortran.dg/proc_decl_12.f90
new file mode 100644 (file)
index 0000000..092c24d
--- /dev/null
@@ -0,0 +1,27 @@
+! { dg-do run }
+!
+! This tests the (partial) fix for PR35830, i.e. handling array arguments
+! with the PROCEDURE statement.
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+module m
+contains
+  subroutine one(a)
+      integer a(1:3)
+      if (any(a /= [1,2,3])) call abort()
+  end subroutine one
+end module m
+
+program test
+  use m
+  implicit none
+  call foo(one)
+contains
+  subroutine foo(f)
+    procedure(one) :: f
+    call f([1,2,3])
+  end subroutine foo
+end program test
+
+! { dg-final { cleanup-modules "m" } }