Index: flang/lib/Semantics/check-omp-structure.h =================================================================== --- flang/lib/Semantics/check-omp-structure.h +++ flang/lib/Semantics/check-omp-structure.h @@ -96,6 +96,10 @@ static OmpDirectiveSet nestedMasterErrSet{ OmpDirectiveSet{llvm::omp::Directive::OMPD_atomic} | taskGeneratingSet | workShareSet}; +static OmpDirectiveSet nestedBarrierErrSet{ + OmpDirectiveSet{Directive::OMPD_critical, Directive::OMPD_ordered, + Directive::OMPD_atomic, Directive::OMPD_master} | + taskGeneratingSet | workShareSet}; static OmpClauseSet privateSet{ Clause::OMPC_private, Clause::OMPC_firstprivate, Clause::OMPC_lastprivate}; static OmpClauseSet privateReductionSet{ @@ -227,6 +231,7 @@ const parser::DefinedOperator::IntrinsicOperator &); void CheckReductionTypeList(const parser::OmpClause::Reduction &); void CheckMasterNesting(const parser::OpenMPBlockConstruct &x); + void CheckBarrierNesting(const parser::OpenMPSimpleStandaloneConstruct &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 @@ -660,10 +660,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,166 @@ +! 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: 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: `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: 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: `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 + !$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 + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$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 + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$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 + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$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 + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$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 + !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. + !$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