Index: flang/lib/Semantics/check-omp-structure.h =================================================================== --- flang/lib/Semantics/check-omp-structure.h +++ flang/lib/Semantics/check-omp-structure.h @@ -76,6 +76,12 @@ static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical, Directive::OMPD_ordered, Directive::OMPD_atomic, Directive::OMPD_task, Directive::OMPD_taskloop}; +static OmpDirectiveSet nestedMasterErrSet{ + OmpDirectiveSet{llvm::omp::Directive::OMPD_do, + llvm::omp::Directive::OMPD_sections, llvm::omp::Directive::OMPD_single, + llvm::omp::Directive::OMPD_workshare, llvm::omp::Directive::OMPD_atomic, + llvm::omp::Directive::OMPD_master} | + taskGeneratingSet}; static OmpClauseSet privateSet{ Clause::OMPC_private, Clause::OMPC_firstprivate, Clause::OMPC_lastprivate}; static OmpClauseSet privateReductionSet{ @@ -200,6 +206,7 @@ bool CheckIntrinsicOperator( const parser::DefinedOperator::IntrinsicOperator &); void CheckReductionTypeList(const parser::OmpClause::Reduction &); + void CheckMasterNesting(const parser::OpenMPBlockConstruct &x); void CheckReductionArraySection(const parser::OmpObjectList &ompObjectList); void CheckIntentInPointerAndDefinable( const parser::OmpObjectList &, const llvm::omp::Clause); Index: flang/lib/Semantics/check-omp-structure.cpp =================================================================== --- flang/lib/Semantics/check-omp-structure.cpp +++ flang/lib/Semantics/check-omp-structure.cpp @@ -366,8 +366,12 @@ HasInvalidWorksharingNesting( beginDir.source, {llvm::omp::Directive::OMPD_do}); } - if (CurrentDirectiveIsNested()) + if (CurrentDirectiveIsNested()) { CheckIfDoOrderedClause(beginDir); + if (GetContext().directive == llvm::omp::Directive::OMPD_master) { + CheckMasterNesting(x); + } + } CheckNoBranching(block, beginDir.v, beginDir.source); @@ -381,6 +385,20 @@ } } +void OmpStructureChecker::CheckMasterNesting( + const parser::OpenMPBlockConstruct &x) { + // A MASTER region may not be `closely nested` inside a worksharing, loop, + // task, taskloop, or atomic region. + // TODO: Expand the check to include `LOOP` construct as well when it is + // supported. + if (IsCloselyNestedRegion(llvm::omp::nestedMasterErrSet)) { + context_.Say(parser::FindSourceLocation(x), + "`MASTER` region may not be closely nested inside of `WORKSHARING`, " + "`LOOP`, `TASK`, `TASKLOOP`," + " or `ATOMIC` region."_err_en_US); + } +} + void OmpStructureChecker::CheckIfDoOrderedClause( const parser::OmpBlockDirective &blkDirective) { if (blkDirective.v == llvm::omp::OMPD_ordered) { Index: flang/test/Semantics/omp-nested-master.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/omp-nested-master.f90 @@ -0,0 +1,130 @@ +! RUN: %S/test_errors.sh %s %t %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! Various checks with the nesting of MASTER construct + +program omp_nest_master + integer i, k, j + k = 0; + + !$omp do + do i = 1, 10 + k = k + 1 + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + j = j -1 + !$omp end master + end do + + !$omp sections + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + do i = 1, 10 + k = k + 1 + end do + !$omp end master + !$omp end sections + + !$omp single + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + do i = 1, 10 + k = k + 1 + end do + !$omp end master + !$omp end single + + + + !$omp task + do i = 1, 10 + k = k + 1 + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + j = j -1 + !$omp end master + end do + !$omp end task + + !$omp taskloop + do i = 1, 10 + k = k + 1 + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + j = j -1 + !$omp end master + end do + !$omp end taskloop + + !$omp critical + do i = 1, 10 + k = k + 1 + !$omp master + j = j -1 + !$omp end master + end do + !$omp end critical + + !$omp ordered + do i = 1, 10 + k = k + 1 + !$omp master + j = j -1 + !$omp end master + end do + !$omp end ordered + + !$omp ordered + do i = 1, 10 + !$omp distribute + do k =1, 10 + print *, "hello" + !$omp master + j = j -1 + !$omp end master + end do + !$omp end distribute + end do + !$omp end ordered + + !$omp critical + do i = 1, 10 + !$omp distribute + do k =1, 10 + print *, "hello" + !$omp master + j = j -1 + !$omp end master + end do + !$omp end distribute + end do + !$omp end critical + + !$omp taskloop + do i = 1, 10 + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + j = j -1 + !$omp end master + end do + !$omp end distribute + end do + !$omp end taskloop + + !$omp task + do i = 1, 10 + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. + !$omp master + j = j -1 + !$omp end master + end do + !$omp end distribute + end do + !$omp end task + +end program omp_nest_master Index: flang/test/Semantics/omp-ordered-simd.f90 =================================================================== --- flang/test/Semantics/omp-ordered-simd.f90 +++ flang/test/Semantics/omp-ordered-simd.f90 @@ -118,6 +118,7 @@ !$OMP TASK C = C - A * B + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$OMP MASTER DO I = 1,N !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. @@ -131,6 +132,7 @@ !$OMP TASKLOOP DO J= 1,N C = C - A * B + !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region. !$OMP MASTER DO I = 1,N !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.