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,10 @@ static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical, Directive::OMPD_ordered, Directive::OMPD_atomic, Directive::OMPD_task, Directive::OMPD_taskloop}; +static OmpDirectiveSet nestedBarrierErrSet{ + OmpDirectiveSet{Directive::OMPD_critical, Directive::OMPD_ordered, + Directive::OMPD_atomic, Directive::OMPD_master} | + taskGeneratingSet | parallelSet | doSet}; static OmpClauseSet privateSet{ Clause::OMPC_private, Clause::OMPC_firstprivate, Clause::OMPC_lastprivate}; static OmpClauseSet privateReductionSet{ @@ -199,6 +203,7 @@ bool CheckReductionOperators(const parser::OmpClause::Reduction &); bool CheckIntrinsicOperator( const parser::DefinedOperator::IntrinsicOperator &); + void CheckBarrierNesting(const parser::OpenMPSimpleStandaloneConstruct &x); void CheckReductionTypeList(const parser::OmpClause::Reduction &); void CheckReductionArraySection(const parser::OmpObjectList &ompObjectList); void CheckIntentInPointerAndDefinable( Index: flang/lib/Semantics/check-omp-structure.cpp =================================================================== --- flang/lib/Semantics/check-omp-structure.cpp +++ flang/lib/Semantics/check-omp-structure.cpp @@ -492,10 +492,27 @@ dirContext_.pop_back(); } +void OmpStructureChecker::CheckBarrierNesting( + const parser::OpenMPSimpleStandaloneConstruct &x) { + // A barrier region may not be `closely nested` inside a worksharing, loop, + // task, taskloop, critical, ordered, atomic, or master region. + // TODO: Expand the check to include `LOOP` construct as well when it is + // supported. + if (GetContext().directive == llvm::omp::Directive::OMPD_barrier) { + if (IsCloselyNestedRegion(llvm::omp::nestedBarrierErrSet)) { + context_.Say(parser::FindSourceLocation(x), + "`BARRIER` region may not be closely nested inside of `WORKSHARING`, " + "`LOOP`, `TASK`, `TASKLOOP`," + "`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region."_err_en_US); + } + } +} + void OmpStructureChecker::Enter( const parser::OpenMPSimpleStandaloneConstruct &x) { const auto &dir{std::get(x.t)}; PushContextAndClauseSets(dir.source, dir.v); + CheckBarrierNesting(x); } void OmpStructureChecker::Leave( Index: flang/test/Semantics/omp-nested-barrier.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/omp-nested-barrier.f90 @@ -0,0 +1,160 @@ +! RUN: %S/test_errors.sh %s %t %flang_fc1 -fopenmp +! OpenMP Version 4.5 +! Various checks with the nesting of BARRIER construct + +program omp_nest_barrier + integer i, k, j + k = 0; + + !$omp do + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + + !$omp do simd + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + + !$omp parallel do + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + + !$omp parallel do simd + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + + !$omp parallel + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end parallel + + !$omp task + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end task + + !$omp taskloop + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end taskloop + + !$omp critical + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end critical + + !$omp master + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end master + + !$omp ordered + do i = 1, 10 + k = k + 1 + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end ordered + + !$omp ordered + do i = 1, 10 + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end distribute + end do + !$omp end ordered + + !$omp master + do i = 1, 10 + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end distribute + end do + !$omp end master + + !$omp critical + do i = 1, 10 + !$omp distribute + do k =1, 10 + print *, "hello" + !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + 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: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + 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: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region. + !$omp barrier + j = j -1 + end do + !$omp end distribute + end do + !$omp end task + +end program omp_nest_barrier