if (llvm::omp::teamSet.test(GetContextParent().directive)) {
HasInvalidTeamsNesting(beginDir.v, beginDir.source);
}
+ if (GetContext().directive == llvm::omp::Directive::OMPD_master) {
+ CheckMasterNesting(x);
+ }
}
CheckNoBranching(block, beginDir.v, beginDir.source);
}
}
+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) {
Directive::OMPD_critical, Directive::OMPD_ordered,
Directive::OMPD_atomic, Directive::OMPD_master} |
workShareSet};
+static OmpDirectiveSet nestedMasterErrSet{
+ OmpDirectiveSet{llvm::omp::Directive::OMPD_atomic} | taskGeneratingSet |
+ workShareSet};
static OmpClauseSet privateSet{
Clause::OMPC_private, Clause::OMPC_firstprivate, Clause::OMPC_lastprivate};
static OmpClauseSet privateReductionSet{
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);
--- /dev/null
+! 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 target parallel do simd
+ do i = 1, 10
+ k = k + 1
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !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 target parallel do simd
+
+ !$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 teams
+ !$omp distribute
+ do k =1, 10
+ print *, "hello"
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+ !$omp end distribute
+ !$omp end teams
+ end do
+ !$omp end ordered
+
+ !$omp critical
+ do i = 1, 10
+ !$omp teams
+ !$omp distribute
+ do k =1, 10
+ print *, "hello"
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+ !$omp end distribute
+ !$omp end teams
+ end do
+ !$omp end critical
+
+ !$omp taskloop
+ do i = 1, 10
+ !$omp teams
+ !$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
+ !$omp end teams
+ end do
+ !$omp end taskloop
+
+ !$omp task
+ do i = 1, 10
+ !$omp teams
+ !$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
+ !$omp end teams
+ end do
+ !$omp end task
+
+end program omp_nest_master
!$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.
!$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.