Re: [PATCH] [PR89773] Fortran OpenACC 'routine' directive refuses procedures with implicit EXTERNAL attribute
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
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
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