diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 39478b58a9070..ea102371334a6 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -1777,7 +1777,6 @@ void OmpAttributeVisitor::ResolveSeqLoopIndexInParallelOrTaskConstruct( // Use of DO CONCURRENT inside OpenMP construct is unspecified behavior // till OpenMP-5.0 standard. // In above both cases we skip the privatization of iteration variables. -// [OpenMP 5.1] DO CONCURRENT indices are private bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) { if (!dirContext_.empty() && GetContext().withinConstruct) { llvm::SmallVector ivs; @@ -1785,20 +1784,6 @@ bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) { const parser::Name *iv{GetLoopIndex(x)}; if (iv && iv->symbol) ivs.push_back(iv); - } else if (x.IsDoConcurrent()) { - const Fortran::parser::LoopControl *loopControl = &*x.GetLoopControl(); - const Fortran::parser::LoopControl::Concurrent &concurrent = - std::get(loopControl->u); - const Fortran::parser::ConcurrentHeader &concurrentHeader = - std::get(concurrent.t); - const std::list &controls = - std::get>( - concurrentHeader.t); - for (const auto &control : controls) { - const parser::Name *iv{&std::get<0>(control.t)}; - if (iv && iv->symbol) - ivs.push_back(iv); - } } ordCollapseLevel--; for (auto iv : ivs) { @@ -1810,9 +1795,6 @@ bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) { if (ordCollapseLevel) { if (const auto *details{iv->symbol->detailsIf()}) { const Symbol *tpSymbol = &details->symbol(); - // TODO: DoConcurrent won't capture the following check because a new - // symbol is declared in ResolveIndexName(), which will not have the - // OmpThreadprivate flag. if (tpSymbol->test(Symbol::Flag::OmpThreadprivate)) { context_.Say(iv->source, "Loop iteration variable %s is not allowed in THREADPRIVATE."_err_en_US, @@ -2119,6 +2101,7 @@ static bool IsPrivatizable(const Symbol *sym) { *sym) && /* OpenMP 5.2, 5.1.1: Assumed-size arrays are shared*/ !sym->owner().IsDerivedType() && sym->owner().kind() != Scope::Kind::ImpliedDos && + sym->owner().kind() != Scope::Kind::Forall && !sym->detailsIf() && !sym->detailsIf() && (!misc || diff --git a/flang/test/Semantics/OpenMP/doconcurrent01.f90 b/flang/test/Semantics/OpenMP/doconcurrent01.f90 index 7e3bdce871dd4..e46fe0ba3127f 100644 --- a/flang/test/Semantics/OpenMP/doconcurrent01.f90 +++ b/flang/test/Semantics/OpenMP/doconcurrent01.f90 @@ -1,7 +1,11 @@ ! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp -! OpenMP 5.1.1 -! DO Concurrent indices are private +! OpenMP 5.2 5.1.1 Variables Referenced in a Construct +! DO CONCURRENT indices have predetermined private DSA. +! +! As DO CONCURRENT indices are defined in the construct itself, and OpenMP +! directives may not appear in it, they are already private. +! Check that index symbols are not modified. !DEF: /private_iv (Subroutine)Subprogram subroutine private_iv @@ -9,7 +13,7 @@ subroutine private_iv integer i !$omp parallel default(private) !$omp single - !DEF: /private_iv/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + !DEF: /private_iv/OtherConstruct1/OtherConstruct1/Forall1/i ObjectEntity INTEGER(4) do concurrent(i=1:2) end do !$omp end single diff --git a/flang/test/Semantics/OpenMP/forall.f90 b/flang/test/Semantics/OpenMP/forall.f90 new file mode 100644 index 0000000000000..58492664a4e85 --- /dev/null +++ b/flang/test/Semantics/OpenMP/forall.f90 @@ -0,0 +1,32 @@ +! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp + +! OpenMP 5.2 5.1.1 Variables Referenced in a Construct +! FORALL indices have predetermined private DSA. +! +! As FORALL indices are defined in the construct itself, and OpenMP +! directives may not appear in it, they are already private. +! Check that index symbols are not modified. + + !DEF: /MainProgram1/a ObjectEntity INTEGER(4) + !DEF: /MainProgram1/b ObjectEntity INTEGER(4) + integer a(5), b(5) + + !REF: /MainProgram1/a + a = 0 + !REF: /MainProgram1/b + b = 0 + + !$omp parallel + !DEF: /MainProgram1/OtherConstruct1/Forall1/i (Implicit) ObjectEntity INTEGER(4) + !DEF: /MainProgram1/OtherConstruct1/a HostAssoc INTEGER(4) + !DEF: /MainProgram1/OtherConstruct1/b HostAssoc INTEGER(4) + forall(i = 1:5) a(i) = b(i) * 2 + !$omp end parallel + + !$omp parallel default(private) + !DEF: /MainProgram1/OtherConstruct2/Forall1/i (Implicit) ObjectEntity INTEGER(4) + !DEF: /MainProgram1/OtherConstruct2/a (OmpPrivate) HostAssoc INTEGER(4) + !DEF: /MainProgram1/OtherConstruct2/b (OmpPrivate) HostAssoc INTEGER(4) + forall(i = 1:5) a(i) = b(i) * 2 + !$omp end parallel +end program