aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/parse.cc
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2023-07-24 22:57:07 +0200
committerTobias Burnus <tobias@codesourcery.com>2023-07-24 22:57:07 +0200
commit2e31fe431b08b0302e1fa8a1c18ee51adafd41df (patch)
tree3d4f7fdbd47af7aa8ae4cc3c0f5b1912030c64de /gcc/fortran/parse.cc
parent31c3b67dfc6e67773d13260bc38b833663698b74 (diff)
downloadgcc-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.cc33
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;