Patchwork [fortran] mixed functions/subroutines in generic interface

login
register
mail settings
Submitter Daniel Franke
Date Dec. 29, 2010, 2:28 a.m.
Message ID <201012290328.05609.franke.daniel@gmail.com>
Download mbox | patch
Permalink /patch/76877/
State New
Headers show

Comments

Daniel Franke - Dec. 29, 2010, 2:28 a.m.
Hi all.

In generic interfaces, procedures must be either all FUNCTIONs or all 
SUBROUTINEs. Currently, if specific INTERFACEs are given, a somewhat cryptic 
warning is printed, if only module procedures are listed, no warning at all is 
provided.

Attached patch gives a readable error message for both cases.


gcc/fortran/:
2010-12-29  Daniel Franke  <franke.daniel@gmail.com>

	PR fortran/33117
	PR fortran/46478
	* parse.c (parse_interface): Remove check for procedure types.
	* interface.c (check_interface0): Verify that procedures are
	either all SUBROUTINEs or all FUNCTIONs.

gcc/testsuite/:
2010-12-29  Daniel Franke  <franke.daniel@gmail.com>

	PR fortran/33117
	PR fortran/46478
	* gfortran.dg/interface_33.f90: New test.

Regression tested on i686-pc-linux-gnu. Ok for trunk?

Cheers

	Daniel
Daniel Franke - Jan. 5, 2011, 10:07 a.m.
On Wednesday 29 December 2010 03:28:05 Daniel Franke wrote:
> In generic interfaces, procedures must be either all FUNCTIONs or all
> SUBROUTINEs. Currently, if specific INTERFACEs are given, a somewhat
> cryptic warning is printed, if only module procedures are listed, no
> warning at all is provided.
> 
> Attached patch gives a readable error message for both cases.

*ping*
Tobias Burnus - Jan. 6, 2011, 2:15 p.m.
On 12/29/2010 03:28 AM, Daniel Franke wrote:
> In generic interfaces, procedures must be either all FUNCTIONs or all
> SUBROUTINEs. Currently, if specific INTERFACEs are given, a somewhat cryptic
> warning is printed, if only module procedures are listed, no warning at all is
> provided.
> Attached patch gives a readable error message for both cases.

OK. Note: The GNU coding style indents the braces of an if/do/for block:
   for
     {
       Blah;
     }
while you use in interface.c (for "if" and "for"):
   for
   {
     Blah;
   }

Cf. http://www.gnu.org/prep/standards/html_node/Formatting.html

Thanks for the patch and sorry for the slow review.

Tobias

> gcc/fortran/:
> 2010-12-29  Daniel Franke<franke.daniel@gmail.com>
>
> 	PR fortran/33117
> 	PR fortran/46478
> 	* parse.c (parse_interface): Remove check for procedure types.
> 	* interface.c (check_interface0): Verify that procedures are
> 	either all SUBROUTINEs or all FUNCTIONs.
>
> gcc/testsuite/:
> 2010-12-29  Daniel Franke<franke.daniel@gmail.com>
>
> 	PR fortran/33117
> 	PR fortran/46478
> 	* gfortran.dg/interface_33.f90: New test.
>
> Regression tested on i686-pc-linux-gnu. Ok for trunk?
>
> Cheers
>
> 	Daniel
Daniel Franke - Jan. 6, 2011, 4:11 p.m.
On Thursday 06 January 2011 15:15:21 Tobias Burnus wrote:
> On 12/29/2010 03:28 AM, Daniel Franke wrote:
> > In generic interfaces, procedures must be either all FUNCTIONs or all
> > SUBROUTINEs. Currently, if specific INTERFACEs are given, a somewhat
> > cryptic warning is printed, if only module procedures are listed, no
> > warning at all is provided.
> > Attached patch gives a readable error message for both cases.
> 
> OK. Note: The GNU coding style indents the braces of an if/do/for block:
[...]

Fixed whitespaces and committed as r168542.

Thanks for the review.

	Daniel
H.J. Lu - Jan. 6, 2011, 7:31 p.m.
On Thu, Jan 6, 2011 at 8:11 AM, Daniel Franke <franke.daniel@gmail.com> wrote:
> On Thursday 06 January 2011 15:15:21 Tobias Burnus wrote:
>> On 12/29/2010 03:28 AM, Daniel Franke wrote:
>> > In generic interfaces, procedures must be either all FUNCTIONs or all
>> > SUBROUTINEs. Currently, if specific INTERFACEs are given, a somewhat
>> > cryptic warning is printed, if only module procedures are listed, no
>> > warning at all is provided.
>> > Attached patch gives a readable error message for both cases.
>>
>> OK. Note: The GNU coding style indents the braces of an if/do/for block:
> [...]
>
> Fixed whitespaces and committed as r168542.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47195

Patch

Index: parse.c
===================================================================
--- parse.c	(revision 168294)
+++ parse.c	(working copy)
@@ -2263,33 +2263,17 @@  loop:
     }
 
 
-  /* Make sure that a generic interface has only subroutines or
-     functions and that the generic name has the right attribute.  */
-  if (current_interface.type == INTERFACE_GENERIC)
-    {
-      if (current_state == COMP_NONE)
-	{
-	  if (new_state == COMP_FUNCTION && sym)
-	    gfc_add_function (&sym->attr, sym->name, NULL);
-	  else if (new_state == COMP_SUBROUTINE && sym)
-	    gfc_add_subroutine (&sym->attr, sym->name, NULL);
-
-	  current_state = new_state;
-	}
-      else
-	{
-	  if (new_state != current_state)
-	    {
-	      if (new_state == COMP_SUBROUTINE)
-		gfc_error ("SUBROUTINE at %C does not belong in a "
-			   "generic function interface");
+  /* Make sure that the generic name has the right attribute.  */
+  if (current_interface.type == INTERFACE_GENERIC
+      && current_state == COMP_NONE)
+  {
+    if (new_state == COMP_FUNCTION && sym)
+      gfc_add_function (&sym->attr, sym->name, NULL);
+    else if (new_state == COMP_SUBROUTINE && sym)
+      gfc_add_subroutine (&sym->attr, sym->name, NULL);
 
-	      if (new_state == COMP_FUNCTION)
-		gfc_error ("FUNCTION at %C does not belong in a "
-			   "generic subroutine interface");
-	    }
-	}
-    }
+    current_state = new_state;
+  }
 
   if (current_interface.type == INTERFACE_ABSTRACT)
     {
Index: interface.c
===================================================================
--- interface.c	(revision 168294)
+++ interface.c	(working copy)
@@ -1092,8 +1092,9 @@  gfc_compare_interfaces (gfc_symbol *s1,
 
 
 /* Given a pointer to an interface pointer, remove duplicate
-   interfaces and make sure that all symbols are either functions or
-   subroutines.  Returns nonzero if something goes wrong.  */
+   interfaces and make sure that all symbols are either functions
+   or subroutines, and all of the same kind.  Returns nonzero if
+   something goes wrong.  */
 
 static int
 check_interface0 (gfc_interface *p, const char *interface_name)
@@ -1101,9 +1102,10 @@  check_interface0 (gfc_interface *p, cons
   gfc_interface *psave, *q, *qlast;
 
   psave = p;
-  /* Make sure all symbols in the interface have been defined as
-     functions or subroutines.  */
   for (; p; p = p->next)
+  {
+    /* Make sure all symbols in the interface have been defined as
+       functions or subroutines.  */
     if ((!p->sym->attr.function && !p->sym->attr.subroutine)
 	|| !p->sym->attr.if_source)
       {
@@ -1116,6 +1118,16 @@  check_interface0 (gfc_interface *p, cons
 		     &p->sym->declared_at);
 	return 1;
       }
+
+    /* Verify that procedures are either all SUBROUTINEs or all FUNCTIONs.  */
+    if ((psave->sym->attr.function && !p->sym->attr.function)
+	|| (psave->sym->attr.subroutine && !p->sym->attr.subroutine))
+    {
+      gfc_error ("In %s at %L procedures must be either all SUBROUTINEs"
+		 " or all FUNCTIONs", interface_name, &p->sym->declared_at);
+      return 1;
+    }
+  }
   p = psave;
 
   /* Remove duplicate interfaces in this interface list.  */