diff options
author | Tobias Burnus <tobias@codesourcery.com> | 2023-07-24 22:57:07 +0200 |
---|---|---|
committer | Tobias Burnus <tobias@codesourcery.com> | 2023-07-24 22:57:07 +0200 |
commit | 2e31fe431b08b0302e1fa8a1c18ee51adafd41df (patch) | |
tree | 3d4f7fdbd47af7aa8ae4cc3c0f5b1912030c64de /gcc/fortran/parse.cc | |
parent | 31c3b67dfc6e67773d13260bc38b833663698b74 (diff) | |
download | gcc-2e31fe431b08b0302e1fa8a1c18ee51adafd41df.zip gcc-2e31fe431b08b0302e1fa8a1c18ee51adafd41df.tar.gz gcc-2e31fe431b08b0302e1fa8a1c18ee51adafd41df.tar.bz2 |
OpenMP/Fortran: Reject not strictly nested target -> teams [PR110725, PR71065]
OpenMP requires: "If a teams region is nested inside a target region, the
corresponding target construct must not contain any statements, declarations
or directives outside of the corresponding teams construct."
This commit checks now for this restriction.
PR fortran/110725
PR middle-end/71065
gcc/fortran/ChangeLog:
* gfortran.h (gfc_omp_clauses): Add contains_teams_construct.
* openmp.cc (resolve_omp_target): New; check for teams nesting.
(gfc_resolve_omp_directive): Call it.
* parse.cc (decode_omp_directive): Set contains_teams_construct
on enclosing ST_OMP_TARGET.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/pr99226.f90: Update dg-error.
* gfortran.dg/gomp/teams-5.f90: New test.
Diffstat (limited to 'gcc/fortran/parse.cc')
-rw-r--r-- | gcc/fortran/parse.cc | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index e53b7a4..011a39c 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -1312,6 +1312,39 @@ decode_omp_directive (void) prog_unit->omp_target_seen = true; break; } + case ST_OMP_TEAMS: + case ST_OMP_TEAMS_DISTRIBUTE: + case ST_OMP_TEAMS_DISTRIBUTE_SIMD: + case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO: + case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: + case ST_OMP_TEAMS_LOOP: + if (gfc_state_stack->previous && gfc_state_stack->previous->tail) + { + gfc_state_data *stk = gfc_state_stack; + do { + stk = stk->previous; + } while (stk && stk->tail && stk->tail->op == EXEC_BLOCK); + if (stk && stk->tail) + switch (stk->tail->op) + { + case EXEC_OMP_TARGET: + case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE: + case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD: + case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO: + case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: + case EXEC_OMP_TARGET_TEAMS_LOOP: + case EXEC_OMP_TARGET_PARALLEL: + case EXEC_OMP_TARGET_PARALLEL_DO: + case EXEC_OMP_TARGET_PARALLEL_DO_SIMD: + case EXEC_OMP_TARGET_PARALLEL_LOOP: + case EXEC_OMP_TARGET_SIMD: + stk->tail->ext.omp_clauses->contains_teams_construct = 1; + break; + default: + break; + } + } + break; case ST_OMP_ERROR: if (new_st.ext.omp_clauses->at != OMP_AT_EXECUTION) return ST_NONE; |