Index: flang/lib/Semantics/check-omp-structure.h =================================================================== --- flang/lib/Semantics/check-omp-structure.h +++ flang/lib/Semantics/check-omp-structure.h @@ -165,7 +165,6 @@ void Enter(const parser::OmpScheduleClause &); private: - bool HasInvalidWorksharingNesting( const parser::CharBlock &, const OmpDirectiveSet &); @@ -175,6 +174,10 @@ llvm::StringRef getClauseName(llvm::omp::Clause clause) override; llvm::StringRef getDirectiveName(llvm::omp::Directive directive) override; + + void CheckDependList(const parser::DataRef &); + void CheckDependArraySection( + const common::Indirection &, const parser::Name &); }; } // namespace Fortran::semantics #endif // FORTRAN_SEMANTICS_CHECK_OMP_STRUCTURE_H_ Index: flang/lib/Semantics/check-omp-structure.cpp =================================================================== --- flang/lib/Semantics/check-omp-structure.cpp +++ flang/lib/Semantics/check-omp-structure.cpp @@ -424,7 +424,6 @@ // Following clauses have a seperate node in parse-tree.h. CHECK_SIMPLE_PARSER_CLAUSE(OmpAllocateClause, OMPC_allocate) CHECK_SIMPLE_PARSER_CLAUSE(OmpDefaultClause, OMPC_default) -CHECK_SIMPLE_PARSER_CLAUSE(OmpDependClause, OMPC_depend) CHECK_SIMPLE_PARSER_CLAUSE(OmpDistScheduleClause, OMPC_dist_schedule) CHECK_SIMPLE_PARSER_CLAUSE(OmpNowait, OMPC_nowait) CHECK_SIMPLE_PARSER_CLAUSE(OmpProcBindClause, OMPC_proc_bind) @@ -597,6 +596,23 @@ } } +void OmpStructureChecker::Enter(const parser::OmpDependClause &x) { + CheckAllowed(llvm::omp::Clause::OMPC_depend); + if (const auto *inOut{std::get_if(&x.u)}) { + const auto &designators{std::get>(inOut->t)}; + for (const auto &ele : designators) { + if (const auto *dataRef{std::get_if(&ele.u)}) { + CheckDependList(*dataRef); + if (const auto *arr{ + std::get_if>( + &dataRef->u)}) { + CheckDependArraySection(*arr, GetLastName(*dataRef)); + } + } + } + } +} + llvm::StringRef OmpStructureChecker::getClauseName(llvm::omp::Clause clause) { return llvm::omp::getOpenMPClauseName(clause); } @@ -606,4 +622,54 @@ return llvm::omp::getOpenMPDirectiveName(directive); } +void OmpStructureChecker::CheckDependList(const parser::DataRef &d) { + std::visit( + common::visitors{ + [&](const common::Indirection &elem) { + // Check if the base element is valid on Depend Clause + CheckDependList(elem.value().base); + }, + [&](const common::Indirection &) { + context_.Say(GetContext().clauseSource, + "A variable that is part of another variable " + "(such as an element of a structure) but is not an array " + "element or an array section cannot appear in a DEPEND " + "clause"_err_en_US); + }, + [&](const common::Indirection &) { + context_.Say(GetContext().clauseSource, + "Coarrays are not supported in DEPEND clause"_err_en_US); + }, + [&](const parser::Name &) { return; }, + }, + d.u); +} + +void OmpStructureChecker::CheckDependArraySection( + const common::Indirection &arr, + const parser::Name &name) { + for (const auto &subscript : arr.value().subscripts) { + if (const auto *triplet{ + std::get_if(&subscript.u)}) { + if (std::get<2>(triplet->t)) { + context_.Say(GetContext().clauseSource, + "Stride should not be specified for array section in DEPEND " + "clause"_err_en_US); + } + const auto &lower{std::get<0>(triplet->t)}; + const auto &upper{std::get<1>(triplet->t)}; + if (lower && upper) { + const auto lval{GetIntValue(lower)}; + const auto uval{GetIntValue(upper)}; + if (lval && uval && *uval < *lval) { + context_.Say(GetContext().clauseSource, + "'%s' in DEPEND clause is a zero size array section"_err_en_US, + name.ToString()); + break; + } + } + } + } +} + } // namespace Fortran::semantics Index: flang/test/Semantics/omp-depend01.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/omp-depend01.f90 @@ -0,0 +1,28 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.13.9 Depend Clause +! List items used in depend clauses cannot be zero-length array sections. + +program omp_depend + integer :: a(10) , b(10,10) + a = 10 + b = 20 + + !$omp parallel + !$omp single + + !ERROR: 'a' in DEPEND clause is a zero size array section + !ERROR: 'b' in DEPEND clause is a zero size array section + !$omp task shared(a,b) depend(out: a(2:1), b(3:1, 1:-1)) + a(2:1) = b(2, 2) + !$omp end task + + !ERROR: Stride should not be specified for array section in DEPEND clause + !$omp task shared(x) depend(in: a(5:10:1)) + print *, a(5:10), b + !$omp end task + + !$omp end single + !$omp end parallel + +end program omp_depend Index: flang/test/Semantics/omp-depend02.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/omp-depend02.f90 @@ -0,0 +1,49 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.13.9 Depend Clause +! A variable that is part of another variable +! (such as an element of a structure) but is not an array element or +! an array section cannot appear in a DEPEND clause + +subroutine vec_mult(N) + implicit none + integer :: i, N + real, allocatable :: p(:), v1(:), v2(:) + + type my_type + integer :: a(10) + end type my_type + + type(my_type) :: my_var + allocate( p(N), v1(N), v2(N) ) + + !$omp parallel num_threads(2) + !$omp single + + !$omp task depend(out:v1) + call init(v1, N) + !$omp end task + + !$omp task depend(out:v2) + call init(v2, N) + !$omp end task + + !ERROR: A variable that is part of another variable (such as an element of a structure) but is not an array element or an array section cannot appear in a DEPEND clause + !$omp target nowait depend(in:v1,v2, my_var%a) depend(out:p) & + !$omp& map(to:v1,v2) map(from: p) + !$omp parallel do + do i=1,N + p(i) = v1(i) * v2(i) + end do + !$omp end target + + !$omp task depend(in:p) + call output(p, N) + !$omp end task + + !$omp end single + !$omp end parallel + + deallocate( p, v1, v2 ) + +end subroutine Index: flang/test/Semantics/omp-depend03.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/omp-depend03.f90 @@ -0,0 +1,24 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.13.9 Depend Clause +! Coarrays are not supported in depend clause + +program omp_depend_coarray + integer :: a(3)[*], b(3) , k + + a(:) = this_image() + b(:) = a(:)[1] + k = 10 + + !$omp parallel + !$omp single + !ERROR: Coarrays are not supported in DEPEND clause + !$omp task shared(b) depend(out: a(:)[1]) + b = a + k + !$omp end task + !$omp end single + !$omp end parallel + + print *, a, b + +end program omp_depend_coarray