Index: flang/lib/Semantics/check-omp-structure.h =================================================================== --- flang/lib/Semantics/check-omp-structure.h +++ flang/lib/Semantics/check-omp-structure.h @@ -42,10 +42,10 @@ Directive::OMPD_teams_distribute_parallel_do, Directive::OMPD_teams_distribute_parallel_do_simd}; static OmpDirectiveSet doSet{Directive::OMPD_distribute_parallel_do, - Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel, - Directive::OMPD_parallel_do, Directive::OMPD_parallel_do_simd, - Directive::OMPD_do, Directive::OMPD_do_simd, - Directive::OMPD_target_parallel_do, Directive::OMPD_target_parallel_do_simd, + Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel_do, + Directive::OMPD_parallel_do_simd, Directive::OMPD_do, + Directive::OMPD_do_simd, Directive::OMPD_target_parallel_do, + Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_teams_distribute_parallel_do, Directive::OMPD_target_teams_distribute_parallel_do_simd, Directive::OMPD_teams_distribute_parallel_do, @@ -55,6 +55,11 @@ Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_teams_distribute_parallel_do_simd, Directive::OMPD_teams_distribute_parallel_do_simd}; +static OmpDirectiveSet workShareSet{ + OmpDirectiveSet{Directive::OMPD_workshare, + Directive::OMPD_parallel_workshare, Directive::OMPD_parallel_sections, + Directive::OMPD_sections, Directive::OMPD_single} | + doSet}; static OmpDirectiveSet taskloopSet{ Directive::OMPD_taskloop, Directive::OMPD_taskloop_simd}; static OmpDirectiveSet targetSet{Directive::OMPD_target, @@ -76,6 +81,11 @@ static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical, Directive::OMPD_ordered, Directive::OMPD_atomic, Directive::OMPD_task, Directive::OMPD_taskloop}; +static OmpDirectiveSet nestedWorkshareErrSet{ + OmpDirectiveSet{Directive::OMPD_task, Directive::OMPD_taskloop, + Directive::OMPD_critical, Directive::OMPD_ordered, + Directive::OMPD_atomic, Directive::OMPD_master} | + workShareSet}; static OmpClauseSet privateSet{ Clause::OMPC_private, Clause::OMPC_firstprivate, Clause::OMPC_lastprivate}; static OmpClauseSet privateReductionSet{ Index: flang/lib/Semantics/check-omp-structure.cpp =================================================================== --- flang/lib/Semantics/check-omp-structure.cpp +++ flang/lib/Semantics/check-omp-structure.cpp @@ -212,16 +212,8 @@ // ordered-clause // nesting check - HasInvalidWorksharingNesting(beginDir.source, - {llvm::omp::Directive::OMPD_do, llvm::omp::Directive::OMPD_sections, - llvm::omp::Directive::OMPD_single, - llvm::omp::Directive::OMPD_workshare, - llvm::omp::Directive::OMPD_task, - llvm::omp::Directive::OMPD_taskloop, - llvm::omp::Directive::OMPD_critical, - llvm::omp::Directive::OMPD_ordered, - llvm::omp::Directive::OMPD_atomic, - llvm::omp::Directive::OMPD_master}); + HasInvalidWorksharingNesting( + beginDir.source, llvm::omp::nestedWorkshareErrSet); } SetLoopInfo(x); @@ -360,12 +352,6 @@ PushContextAndClauseSets(beginDir.source, beginDir.v); - // TODO: This check needs to be extended while implementing nesting of regions - // checks. - if (beginDir.v == llvm::omp::Directive::OMPD_single) { - HasInvalidWorksharingNesting( - beginDir.source, {llvm::omp::Directive::OMPD_do}); - } if (CurrentDirectiveIsNested()) CheckIfDoOrderedClause(beginDir); @@ -375,6 +361,14 @@ case llvm::omp::OMPD_workshare: case llvm::omp::OMPD_parallel_workshare: CheckWorkshareBlockStmts(block, beginDir.source); + HasInvalidWorksharingNesting( + beginDir.source, llvm::omp::nestedWorkshareErrSet); + break; + case llvm::omp::Directive::OMPD_single: + // TODO: This check needs to be extended while implementing nesting of + // regions checks. + HasInvalidWorksharingNesting( + beginDir.source, llvm::omp::nestedWorkshareErrSet); break; default: break; @@ -420,6 +414,8 @@ for (const auto &block : sectionBlocks.v) { CheckNoBranching(block, beginDir.v, beginDir.source); } + HasInvalidWorksharingNesting( + beginDir.source, llvm::omp::nestedWorkshareErrSet); } void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) { Index: flang/test/Semantics/omp-do05.f90 =================================================================== --- flang/test/Semantics/omp-do05.f90 +++ flang/test/Semantics/omp-do05.f90 @@ -18,6 +18,94 @@ end do !$omp end do + !$omp parallel do + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end parallel do + + !$omp parallel do simd + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end parallel do simd + + !$omp distribute parallel do + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end distribute parallel do + + !$omp distribute parallel do simd + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end distribute parallel do simd + + !$omp target parallel do + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end target parallel do + + !$omp target parallel do simd + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end target parallel do simd + + !$omp target teams distribute parallel do + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end target teams distribute parallel do + + !$omp target teams distribute parallel do simd + do i=1,10 + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region + !$omp single + do j=1,10 + print *,"hello" + end do + !$omp end single + end do + !$omp end target teams distribute parallel do simd + !$omp do do i=1,10 !$omp task Index: flang/test/Semantics/omp-workshare01.f90 =================================================================== --- flang/test/Semantics/omp-workshare01.f90 +++ flang/test/Semantics/omp-workshare01.f90 @@ -15,6 +15,7 @@ end do !$omp critical + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region !$omp single aa = bb !$omp end single Index: flang/test/Semantics/omp-workshare04.f90 =================================================================== --- flang/test/Semantics/omp-workshare04.f90 +++ flang/test/Semantics/omp-workshare04.f90 @@ -18,7 +18,9 @@ !$omp end parallel !ERROR: OpenMP constructs enclosed in WORKSHARE construct may consist of ATOMIC, CRITICAL or PARALLEL constructs only + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region !$omp parallel workshare + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region !$omp single ee = ff !$omp end single Index: flang/test/Semantics/omp-workshare05.f90 =================================================================== --- flang/test/Semantics/omp-workshare05.f90 +++ flang/test/Semantics/omp-workshare05.f90 @@ -40,6 +40,7 @@ !$omp end single !$omp end parallel + !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region !$omp parallel sections !$omp section aa = my_func()