Fortran: Fix OpenACC in specification-part checks [PR90111]

OpenACC's routine and declare directives can appear anywhere in the
specification part, i.e. before/after use-stmts, import-stmt, implicit-part,
or declaration-constructs.

gcc/fortran/ChangeLog:

	PR fortran/90111
	* parse.c (case_decl): Move ST_OACC_ROUTINE and ST_OACC_DECLARE to ...
	(case_omp_decl): ... here.
	(verify_st_order): Update comment.

gcc/testsuite/ChangeLog:

	PR fortran/90111
	* gfortran.dg/goacc/specification-part.f90: New test.
This commit is contained in:
Tobias Burnus 2020-11-09 16:16:44 +01:00
parent b2b8516373
commit f27a3b37b4
2 changed files with 106 additions and 5 deletions

View file

@ -1633,14 +1633,15 @@ next_statement (void)
#define case_decl case ST_ATTR_DECL: case ST_COMMON: case ST_DATA_DECL: \
case ST_EQUIVALENCE: case ST_NAMELIST: case ST_STATEMENT_FUNCTION: \
case ST_TYPE: case ST_INTERFACE: case ST_PROCEDURE: case ST_OACC_ROUTINE: \
case ST_OACC_DECLARE
case ST_TYPE: case ST_INTERFACE: case ST_PROCEDURE
/* OpenMP declaration statements. */
/* OpenMP and OpenACC declaration statements, which may appear anywhere in
the specification part. */
#define case_omp_decl case ST_OMP_THREADPRIVATE: case ST_OMP_DECLARE_SIMD: \
case ST_OMP_DECLARE_TARGET: case ST_OMP_DECLARE_REDUCTION: \
case ST_OMP_REQUIRES
case ST_OMP_REQUIRES: case ST_OACC_ROUTINE: case ST_OACC_DECLARE
/* Block end statements. Errors associated with interchanging these
are detected in gfc_match_end(). */
@ -2813,7 +2814,7 @@ verify_st_order (st_state *p, gfc_statement st, bool silent)
break;
case_omp_decl:
/* The OpenMP directives have to be somewhere in the specification
/* The OpenMP/OpenACC directives have to be somewhere in the specification
part, but there are no further requirements on their ordering.
Thus don't adjust p->state, just ignore them. */
if (p->state >= ORDER_EXEC)

View file

@ -0,0 +1,100 @@
! { dg-do compile }
!
! PR fortran/90111
!
! Check that OpenACC directives in everywhere in specification part,
! i.e. it may appear before/after the use, import, implicit, and declaration
!
module m
end module m
subroutine foo0(kk)
use m
implicit none
integer :: jj, kk
!$acc routine
end
subroutine foo1()
use m
implicit none
!$acc routine
integer :: jj
end
subroutine foo2()
use m
!$acc routine
implicit none
end
subroutine foo3()
!$acc routine
use m
implicit none
end
module m2
interface
subroutine foo0(kk)
use m
import
implicit none
integer :: kk
!$acc routine
end
subroutine foo1()
use m
import
implicit none
!$acc routine
end
subroutine foo2()
use m
import
!$acc routine
implicit none
end
subroutine foo3()
use m
!$acc routine
import
implicit none
end
subroutine foo4()
use m
!$acc routine
import
implicit none
end
end interface
end module m2
subroutine bar0()
use m
implicit none
integer :: ii
!$acc declare copyin(ii)
end
subroutine bar1()
use m
implicit none
!$acc declare copyin(ii)
integer :: ii
end
subroutine bar2()
use m
!$acc declare copyin(ii)
implicit none
integer :: ii
end
subroutine bar3()
!$acc declare copyin(ii)
use m
implicit none
integer :: ii
end