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
Related show

Commit Message

Steve Kargl March 21, 2018, 10:19 p.m.
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

Comments

Janne Blomqvist March 22, 2018, 8:22 a.m. | #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.

-- 
Janne Blomqvist
Steve Kargl March 22, 2018, 7:32 p.m. | #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 ;-)

-- 
Steve
20170425 https://www.youtube.com/watch?v=VWUpyCsUKR4
20161221 https://www.youtube.com/watch?v=IbCHE-hONow

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