Index: flang/lib/Semantics/check-omp-structure.h =================================================================== --- flang/lib/Semantics/check-omp-structure.h +++ flang/lib/Semantics/check-omp-structure.h @@ -73,6 +73,9 @@ Directive::OMPD_teams_distribute_simd}; static OmpDirectiveSet taskGeneratingSet{ OmpDirectiveSet{Directive::OMPD_task} | taskloopSet}; +static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical, + Directive::OMPD_ordered, Directive::OMPD_atomic, Directive::OMPD_task, + Directive::OMPD_taskloop}; 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 @@ -343,12 +343,22 @@ void OmpStructureChecker::CheckIfDoOrderedClause( const parser::OmpBlockDirective &blkDirective) { if (blkDirective.v == llvm::omp::OMPD_ordered) { - if (!FindClauseParent(llvm::omp::Clause::OMPC_ordered)) { + // Loops + if (llvm::omp::doSet.test(GetContextParent().directive) && + !FindClauseParent(llvm::omp::Clause::OMPC_ordered)) { context_.Say(blkDirective.source, "The ORDERED clause must be present on the loop" " construct if any ORDERED region ever binds" " to a loop region arising from the loop construct."_err_en_US); } + // Other disallowed nestings, these directives do not support + // ordered clause in them, so no need to check + else if (llvm::omp::nestedOrderedErrSet.test( + GetContextParent().directive)) { + context_.Say(blkDirective.source, + "`ORDERED` region may not be closely nested inside of " + "`CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region."_err_en_US); + } } } Index: flang/test/Semantics/omp-ordered-simd.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/omp-ordered-simd.f90 @@ -0,0 +1,95 @@ +! RUN: %S/test_errors.sh %s %t %flang -fopenmp +! OpenMP Version 4.5 +! Various checks with the ordered construct + +SUBROUTINE WORK(I) + INTEGER I +END SUBROUTINE WORK + +SUBROUTINE ORDERED_GOOD(N) + INTEGER N, I, A(10), B(10), C(10) + !$OMP SIMD + DO I = 1,N + IF (I <= 10) THEN + !$OMP ORDERED SIMD + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END SIMD +END SUBROUTINE ORDERED_GOOD + +SUBROUTINE ORDERED_BAD(N) + INTEGER N, I, A(10), B(10), C(10) + + !$OMP DO SIMD + DO I = 1,N + IF (I <= 10) THEN + !ERROR: The ORDERED clause must be present on the loop construct if any ORDERED region ever binds to a loop region arising from the loop construct. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END DO SIMD + + !$OMP PARALLEL DO + DO I = 1,N + IF (I <= 10) THEN + !ERROR: The ORDERED clause must be present on the loop construct if any ORDERED region ever binds to a loop region arising from the loop construct. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END PARALLEL DO + + !$OMP CRITICAL + DO I = 1,N + IF (I <= 10) THEN + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END CRITICAL + + !$OMP CRITICAL + WRITE(*,*) I + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + !$OMP END CRITICAL + + !$OMP ORDERED + WRITE(*,*) I + IF (I <= 10) THEN + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + !$OMP END ORDERED + + !$OMP TASK + C = C - A * B + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + !$OMP END TASK + + !$OMP TASKLOOP + DO I = 1,N + IF (I <= 10) THEN + !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region. + !$OMP ORDERED + CALL WORK(I) + !$OMP END ORDERED + ENDIF + END DO + !$OMP END TASKLOOP + +END SUBROUTINE ORDERED_BAD