Re: [PATCH] [PR89773] Fortran OpenACC 'routine' directive refuses procedures with implicit EXTERNAL attribute

2019-03-21 Thread Steve Kargl
On Thu, Mar 21, 2019 at 09:04:21PM +0100, Thomas Schwinge wrote:
> Hi!
> 
> On Wed, 20 Mar 2019 11:07:31 +0100, I wrote:
> > On Fri, 26 Aug 2016 08:16:43 -0700, Cesar Philippidis 
> >  wrote:
> > > While working on [...], I noticed
> > 
> > If only all such issues would end up in their own PRs, instead of mixing
> > them with other changes...
> > 
> > > that the fortran FE wasn't permitting
> > > named functions inside acc routine directives. E.g.
> > > 
> > >   integer :: foo
> > >   !$acc routine(foo) gang
> > > 
> > >   ... = foo ()
> > 
> > ACK.  Perhaps not the most pretty style, but gfortran does accept this.
> > 
> > Do I understand right that there exists no equivalent syntax in Fortran
> > to declare a subroutine (instead of a function) with implicit EXTERNAL
> > attribute?  (See also the new 'gfortran.dg/goacc/pr89773.f90' test case
> > I'm adding.)
> 
> (Still interested if there's a way to do that.)
> 

You're question make so sense to me as it seems you're 
conflating IMPLICIT type with implicit interface.  The
F2018 standard has

  15.4.2.1 Interfaces and scopes

  The interface of a procedure is either explicit or implicit.
  It is explicit if it is 
. an internal procedure, module procedure, or intrinsic procedure,
· a subroutine, or a function with a separate result name, within
  the scoping unit that defines it, or
· a procedure declared by a procedure declaration statement that
  specifies an explicit interface, or by an interface body.

  Otherwise, the interface of the identifier is implicit.  The interface
  of a statement function is always implicit.

These two program are equivalent

program foo
  external bar
  external bah
  call bar(a,i)
  x = bah()
end program

program foo
  call bar(a,i)
  x = bah()
end program

except the former explicitly tells the compiler that bar and bah
are external.  The "return type" with respect to C of bar is always
void.  All subroutines with either an explicit or implicit interface
have a void "return type".  The return type for bah() is *implicitly*
determined by the 'b' in the function function name.  In this case,
bar() has an implcit type of REAL.

-- 
Steve


Re: [PATCH] [PR89773] Fortran OpenACC 'routine' directive refuses procedures with implicit EXTERNAL attribute

2019-03-21 Thread Thomas Schwinge
Hi!

On Wed, 20 Mar 2019 11:07:31 +0100, I wrote:
> On Fri, 26 Aug 2016 08:16:43 -0700, Cesar Philippidis 
>  wrote:
> > While working on [...], I noticed
> 
> If only all such issues would end up in their own PRs, instead of mixing
> them with other changes...
> 
> > that the fortran FE wasn't permitting
> > named functions inside acc routine directives. E.g.
> > 
> >   integer :: foo
> >   !$acc routine(foo) gang
> > 
> >   ... = foo ()
> 
> ACK.  Perhaps not the most pretty style, but gfortran does accept this.
> 
> Do I understand right that there exists no equivalent syntax in Fortran
> to declare a subroutine (instead of a function) with implicit EXTERNAL
> attribute?  (See also the new 'gfortran.dg/goacc/pr89773.f90' test case
> I'm adding.)

(Still interested if there's a way to do that.)

> > This patch also fixes this issue. But to do that, I had to add a
> > gfc_resolve_oacc_routines pass in order to identify if a variable is a
> > function or variable because that information isn't available during
> > matching.
> 
> OK to fix this as in the attached patch?

I convinced myself that my proposed changes are the right thing to do,
and committed to trunk r269857 "[PR89773] Fortran OpenACC 'routine'
directive refuses procedures with implicit EXTERNAL attribute", see
attached.


Grüße
 Thomas


From cbfb10ec630fc5829bdfebbf59ba40d22874c9e2 Mon Sep 17 00:00:00 2001
From: tschwinge 
Date: Thu, 21 Mar 2019 20:02:42 +
Subject: [PATCH] [PR89773] Fortran OpenACC 'routine' directive refuses
 procedures with implicit EXTERNAL attribute

	gcc/fortran/
	PR fortran/89773
	* gfortran.h (gfc_oacc_routine_name): Add loc member.
	(gfc_resolve_oacc_routines): Declare.
	* openmp.c (gfc_match_oacc_routine): Move some error checking
	into...
	(gfc_resolve_oacc_routines): ... this new function.
	* resolve.c (resolve_codes): Call it.
	gcc/testsuite/
	PR fortran/89773
	* gfortran.dg/goacc/pr89773.f90: New file.
	* gfortran.dg/goacc/pr77765.f90: Adjust.
	* gfortran.dg/goacc/routine-6.f90: Adjust, and extend.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@269857 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/fortran/ChangeLog |  8 +
 gcc/fortran/gfortran.h|  2 ++
 gcc/fortran/openmp.c  | 33 -
 gcc/fortran/resolve.c |  1 +
 gcc/testsuite/ChangeLog   |  5 +++
 gcc/testsuite/gfortran.dg/goacc/pr77765.f90   |  2 +-
 gcc/testsuite/gfortran.dg/goacc/pr89773.f90   | 36 +++
 gcc/testsuite/gfortran.dg/goacc/routine-6.f90 | 21 +--
 8 files changed, 96 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/goacc/pr89773.f90

diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 111e3a266e9b..7ce67eb46fe7 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,5 +1,13 @@
 2019-03-21  Thomas Schwinge  
 
+	PR fortran/89773
+	* gfortran.h (gfc_oacc_routine_name): Add loc member.
+	(gfc_resolve_oacc_routines): Declare.
+	* openmp.c (gfc_match_oacc_routine): Move some error checking
+	into...
+	(gfc_resolve_oacc_routines): ... this new function.
+	* resolve.c (resolve_codes): Call it.
+
 	PR fortran/72741
 	* openmp.c (gfc_match_oacc_routine): Clarify.
 
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 2f55b9c387a6..caf5e528c7e0 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1739,6 +1739,7 @@ typedef struct gfc_oacc_routine_name
   struct gfc_symbol *sym;
   struct gfc_omp_clauses *clauses;
   struct gfc_oacc_routine_name *next;
+  locus loc;
 }
 gfc_oacc_routine_name;
 
@@ -3210,6 +3211,7 @@ void gfc_resolve_oacc_directive (gfc_code *, gfc_namespace *);
 void gfc_resolve_oacc_declare (gfc_namespace *);
 void gfc_resolve_oacc_parallel_loop_blocks (gfc_code *, gfc_namespace *);
 void gfc_resolve_oacc_blocks (gfc_code *, gfc_namespace *);
+void gfc_resolve_oacc_routines (gfc_namespace *);
 
 /* expr.c */
 void gfc_free_actual_arglist (gfc_actual_arglist *);
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 1b1a0b4108fd..983b83db4a7b 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -2322,15 +2322,10 @@ gfc_match_oacc_routine (void)
 	sym = NULL;
 	}
 
-	  if ((isym == NULL && st == NULL)
-	  || (sym
-		  && !sym->attr.external
-		  && !sym->attr.function
-		  && !sym->attr.subroutine))
+	  if (isym == NULL && st == NULL)
 	{
-	  gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, "
-			 "invalid function name %s",
-			 (sym) ? sym->name : buffer);
+	  gfc_error ("Invalid NAME %qs in !$ACC ROUTINE ( NAME ) at %C",
+			 buffer);
 	  gfc_current_locus = old_loc;
 	  return MATCH_ERROR;
 	}
@@ -2400,6 +2395,7 @@ gfc_m

[PATCH] [PR89773] Fortran OpenACC 'routine' directive refuses procedures with implicit EXTERNAL attribute

2019-03-20 Thread Thomas Schwinge
Hi!

On Fri, 26 Aug 2016 08:16:43 -0700, Cesar Philippidis  
wrote:
> While working on [...], I noticed

If only all such issues would end up in their own PRs, instead of mixing
them with other changes...

> that the fortran FE wasn't permitting
> named functions inside acc routine directives. E.g.
> 
>   integer :: foo
>   !$acc routine(foo) gang
> 
>   ... = foo ()

ACK.  Perhaps not the most pretty style, but gfortran does accept this.

Do I understand right that there exists no equivalent syntax in Fortran
to declare a subroutine (instead of a function) with implicit EXTERNAL
attribute?  (See also the new 'gfortran.dg/goacc/pr89773.f90' test case
I'm adding.)

> This patch also fixes this issue. But to do that, I had to add a
> gfc_resolve_oacc_routines pass in order to identify if a variable is a
> function or variable because that information isn't available during
> matching.

OK to fix this as in the attached patch?  If approving this patch, please
respond with "Reviewed-by: NAME " so that your effort will be
recorded in the commit log, see <https://gcc.gnu.org/wiki/Reviewed-by>.


Grüße
 Thomas


>From 38d953f51280e6fc327af6b8e35e10ef5d70d589 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge 
Date: Wed, 20 Mar 2019 10:58:58 +0100
Subject: [PATCH] [PR89773] Fortran OpenACC 'routine' directive refuses
 procedures with implicit EXTERNAL attribute

	gcc/fortran/
	PR fortran/89773
	* gfortran.h (gfc_oacc_routine_name): Add loc member.
	(gfc_resolve_oacc_routines): Declare.
	* openmp.c (gfc_match_oacc_routine): Move some error checking
	into...
	(gfc_resolve_oacc_routines): ... this new function.
	* resolve.c (resolve_codes): Call it.
	gcc/testsuite/
	PR fortran/89773
	* gfortran.dg/goacc/pr89773.f90: New file.
	* gfortran.dg/goacc/pr77765.f90: Adjust.
	* gfortran.dg/goacc/routine-6.f90: Adjust, and extend.
---
 gcc/fortran/gfortran.h|  2 ++
 gcc/fortran/openmp.c  | 30 +++-
 gcc/fortran/resolve.c |  1 +
 gcc/testsuite/gfortran.dg/goacc/pr77765.f90   |  2 +-
 gcc/testsuite/gfortran.dg/goacc/pr89773.f90   | 36 +++
 gcc/testsuite/gfortran.dg/goacc/routine-6.f90 | 21 +--
 6 files changed, 80 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/goacc/pr89773.f90

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 2f55b9c387a6..caf5e528c7e0 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1739,6 +1739,7 @@ typedef struct gfc_oacc_routine_name
   struct gfc_symbol *sym;
   struct gfc_omp_clauses *clauses;
   struct gfc_oacc_routine_name *next;
+  locus loc;
 }
 gfc_oacc_routine_name;
 
@@ -3210,6 +3211,7 @@ void gfc_resolve_oacc_directive (gfc_code *, gfc_namespace *);
 void gfc_resolve_oacc_declare (gfc_namespace *);
 void gfc_resolve_oacc_parallel_loop_blocks (gfc_code *, gfc_namespace *);
 void gfc_resolve_oacc_blocks (gfc_code *, gfc_namespace *);
+void gfc_resolve_oacc_routines (gfc_namespace *);
 
 /* expr.c */
 void gfc_free_actual_arglist (gfc_actual_arglist *);
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 7a06eb58f5cf..69b05084dc06 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -2319,15 +2319,10 @@ gfc_match_oacc_routine (void)
 	sym = NULL;
 	}
 
-	  if ((isym == NULL && st == NULL)
-	  || (sym
-		  && !sym->attr.external
-		  && !sym->attr.function
-		  && !sym->attr.subroutine))
+	  if (isym == NULL && st == NULL)
 	{
-	  gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, "
-			 "invalid function name %s",
-			 (sym) ? sym->name : buffer);
+	  gfc_error ("Invalid NAME %qs in !$ACC ROUTINE ( NAME ) at %C",
+			 buffer);
 	  gfc_current_locus = old_loc;
 	  return MATCH_ERROR;
 	}
@@ -2397,6 +2392,7 @@ gfc_match_oacc_routine (void)
 	  n->sym = sym;
 	  n->clauses = c;
 	  n->next = gfc_current_ns->oacc_routine_names;
+	  n->loc = old_loc;
 	  gfc_current_ns->oacc_routine_names = n;
 	}
 }
@@ -6069,6 +6065,24 @@ gfc_resolve_oacc_declare (gfc_namespace *ns)
 }
 }
 
+
+void
+gfc_resolve_oacc_routines (gfc_namespace *ns)
+{
+  for (gfc_oacc_routine_name *orn = ns->oacc_routine_names;
+   orn;
+   orn = orn->next)
+{
+  gfc_symbol *sym = orn->sym;
+  if (!sym->attr.external
+	  && !sym->attr.function
+	  && !sym->attr.subroutine)
+	gfc_error ("NAME %qs does not refer to a subroutine or function"
+		   " in !$ACC ROUTINE ( NAME ) at %L", sym->name, >loc);
+}
+}
+
+
 void
 gfc_resolve_oacc_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
 {
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 7539aa7038c4..e1cd2007e59a 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -16818,6 +1