diff mbox series

PR fortran/84922 -- Check MODULE prefix is used

Message ID 20180321221906.GA76669@troutmask.apl.washington.edu
State New
Headers show
Series PR fortran/84922 -- Check MODULE prefix is used | expand

Commit Message

Steve Kargl March 21, 2018, 10:19 p.m. UTC
If an interface body includes a MODULE prefix on a subroutine
or function, then the prefix must appear on the contained
subprogram.  This patch does that check, and issues an error
message.

2018-03-21  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/84922
	* decl.c (get_proc_name): If the MODULE prefix appears in interface
	body, then it must appear on the contained subroutine or function.
	While here, fix nearby mis-indented code.

2018-03-21  Steven G. Kargl  <kargl@gcc.gnu.org

	PR fortran/84922
	* gfortran.dg/interface_42.f90: New test.
	* gfortran.dg/interface_43.f90: New test.

Comments

Janne Blomqvist March 22, 2018, 8:22 a.m. UTC | #1
On Thu, Mar 22, 2018 at 12:19 AM, Steve Kargl <
sgk@troutmask.apl.washington.edu> wrote:

> If an interface body includes a MODULE prefix on a subroutine
> or function, then the prefix must appear on the contained
> subprogram.  This patch does that check, and issues an error
> message.
>
> 2018-03-21  Steven G. Kargl  <kargl@gcc.gnu.org>
>
>         PR fortran/84922
>         * decl.c (get_proc_name): If the MODULE prefix appears in interface
>         body, then it must appear on the contained subroutine or function.
>         While here, fix nearby mis-indented code.
>
> 2018-03-21  Steven G. Kargl  <kargl@gcc.gnu.org
>
>         PR fortran/84922
>         * gfortran.dg/interface_42.f90: New test.
>         * gfortran.dg/interface_43.f90: New test.
> --
> Steve
>



In the testcase, please change the "modified by me" comment to specify who
"me" is.

Otherwise Ok.
Steve Kargl March 22, 2018, 7:32 p.m. UTC | #2
On Thu, Mar 22, 2018 at 10:22:48AM +0200, Janne Blomqvist wrote:
> On Thu, Mar 22, 2018 at 12:19 AM, Steve Kargl <
> sgk@troutmask.apl.washington.edu> wrote:
> 
> > If an interface body includes a MODULE prefix on a subroutine
> > or function, then the prefix must appear on the contained
> > subprogram.  This patch does that check, and issues an error
> > message.
> >
> > 2018-03-21  Steven G. Kargl  <kargl@gcc.gnu.org>
> >
> >         PR fortran/84922
> >         * decl.c (get_proc_name): If the MODULE prefix appears in interface
> >         body, then it must appear on the contained subroutine or function.
> >         While here, fix nearby mis-indented code.
> >
> > 2018-03-21  Steven G. Kargl  <kargl@gcc.gnu.org
> >
> >         PR fortran/84922
> >         * gfortran.dg/interface_42.f90: New test.
> >         * gfortran.dg/interface_43.f90: New test.
> > --
> > Steve
> >
> 
> In the testcase, please change the "modified by me" comment to specify who
> "me" is.
> 

Thank.  Just checking to see if people read the patch ;-)
diff mbox series

Patch

Index: gcc/fortran/decl.c
===================================================================
--- gcc/fortran/decl.c	(revision 258727)
+++ gcc/fortran/decl.c	(working copy)
@@ -1245,16 +1245,27 @@  get_proc_name (const char *name, gfc_symbol **result, 
 		       "from a previous declaration",  name);
     }
 
-    if (sym && !sym->gfc_new
-	&& sym->attr.flavor != FL_UNKNOWN
-	&& sym->attr.referenced == 0 && sym->attr.subroutine == 1
-	&& gfc_state_stack->state == COMP_CONTAINS
-	&& gfc_state_stack->previous->state == COMP_SUBROUTINE)
-    {
-	gfc_error_now ("Procedure %qs at %C is already defined at %L",
-		       name, &sym->declared_at);
-    }
+  /* C1246 (R1225) MODULE shall appear only in the function-stmt or
+     subroutine-stmt of a module subprogram or of a nonabstract interface
+     body that is declared in the scoping unit of a module or submodule.  */
+  if (sym->attr.external
+      && (sym->attr.subroutine || sym->attr.function)
+      && sym->attr.if_source == IFSRC_IFBODY
+      && !current_attr.module_procedure
+      && sym->attr.proc == PROC_MODULE
+      && gfc_state_stack->state == COMP_CONTAINS)
+    gfc_error_now ("Procedure %qs defined in interface body at %L "
+		   "clashes with internal procedure defined at %C",
+		    name, &sym->declared_at);
 
+  if (sym && !sym->gfc_new
+      && sym->attr.flavor != FL_UNKNOWN
+      && sym->attr.referenced == 0 && sym->attr.subroutine == 1
+      && gfc_state_stack->state == COMP_CONTAINS
+      && gfc_state_stack->previous->state == COMP_SUBROUTINE)
+    gfc_error_now ("Procedure %qs at %C is already defined at %L",
+		    name, &sym->declared_at);
+
   if (gfc_current_ns->parent == NULL || *result == NULL)
     return rc;
 
Index: gcc/testsuite/gfortran.dg/interface_42.f90
===================================================================
--- gcc/testsuite/gfortran.dg/interface_42.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/interface_42.f90	(working copy)
@@ -0,0 +1,24 @@ 
+! { dg-do compile }
+! { dg-options "-fmax-errors=1" }
+! PR fortran/84922
+! Code contributed by William Clodius, but simplified by me.
+module copy
+
+   interface
+      module subroutine foo_da(da, copy) ! { dg-error "(1)" }
+         integer, intent(in) :: da(:)
+         integer, allocatable, intent(out) :: copy(:)
+      end subroutine foo_da
+   end interface
+
+   contains
+
+      subroutine foo_da(da, copy) ! { dg-error "defined in interface body" }
+         integer, intent(in) :: da(:)
+         integer, allocatable, intent(out) :: copy(:)
+         allocate( copy( size(da) ) )
+         copy = da
+      end subroutine foo_da
+
+end module copy
+{ dg-prune-output "compilation terminated" }
Index: gcc/testsuite/gfortran.dg/interface_43.f90
===================================================================
--- gcc/testsuite/gfortran.dg/interface_43.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/interface_43.f90	(working copy)
@@ -0,0 +1,25 @@ 
+! { dg-do compile }
+! PR fortran/84922
+! This should compile without error.
+module foom
+
+   implicit none
+
+   interface foo
+      module procedure foo_sngl
+      module procedure foo_dble
+   end interface foo
+
+   contains
+
+      subroutine foo_sngl(n, f, g, h)
+         integer n
+         real f, g, h
+      end subroutine foo_sngl
+
+      subroutine foo_dble(n, f, g, h)
+         integer n
+         double precision f, g, h
+      end subroutine foo_dble
+
+end module foom