diff options
Diffstat (limited to 'flang')
-rw-r--r-- | flang/include/flang/Parser/parse-tree.h | 2 | ||||
-rw-r--r-- | flang/lib/Lower/OpenMP.cpp | 3 | ||||
-rw-r--r-- | flang/lib/Parser/openmp-parsers.cpp | 2 | ||||
-rw-r--r-- | flang/lib/Parser/unparse.cpp | 2 | ||||
-rw-r--r-- | flang/lib/Semantics/check-omp-structure.cpp | 12 | ||||
-rw-r--r-- | flang/test/Semantics/omp-clause-validity01.f90 | 1 | ||||
-rw-r--r-- | flang/test/Semantics/omp-flush01.f90 | 39 | ||||
-rw-r--r-- | flang/test/Semantics/omp-flush02.f90 | 86 |
8 files changed, 142 insertions, 5 deletions
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 5d2909a4142a..27998c308cc0 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3747,7 +3747,7 @@ struct OpenMPCancelConstruct { struct OpenMPFlushConstruct { TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct); CharBlock source; - std::tuple<Verbatim, std::optional<OmpMemoryOrderClause>, + std::tuple<Verbatim, std::optional<std::list<OmpMemoryOrderClause>>, std::optional<OmpObjectList>> t; }; diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index cfe4b0b86b67..97946caa68a0 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -109,7 +109,8 @@ genOMP(Fortran::lower::AbstractConverter &converter, std::get<std::optional<Fortran::parser::OmpObjectList>>( flushConstruct.t)) genObjectList(*ompObjectList, converter, operandRange); - if (std::get<std::optional<Fortran::parser::OmpMemoryOrderClause>>( + if (std::get<std::optional< + std::list<Fortran::parser::OmpMemoryOrderClause>>>( flushConstruct.t)) TODO("Handle OmpMemoryOrderClause"); converter.getFirOpBuilder().create<mlir::omp::FlushOp>( diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index fd209abc4138..67c377e798ca 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -331,7 +331,7 @@ TYPE_PARSER(sourced(construct<OmpAtomicClauseList>( many(maybe(","_tok) >> sourced(Parser<OmpAtomicClause>{}))))) TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(verbatim("FLUSH"_tok), - maybe(Parser<OmpMemoryOrderClause>{}), + many(maybe(","_tok) >> sourced(Parser<OmpMemoryOrderClause>{})), maybe(parenthesized(Parser<OmpObjectList>{}))))) // Simple Standalone Directives diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index c5df6990d102..bd1c1a2c71eb 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2460,7 +2460,7 @@ public: void Unparse(const OpenMPFlushConstruct &x) { BeginOpenMP(); Word("!$OMP FLUSH "); - Walk(std::get<std::optional<OmpMemoryOrderClause>>(x.t)); + Walk(std::get<std::optional<std::list<OmpMemoryOrderClause>>>(x.t)); Walk(" (", std::get<std::optional<OmpObjectList>>(x.t), ")"); Put("\n"); EndOpenMP(); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index e58e2e509fb8..978e1c7962a4 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -226,7 +226,17 @@ void OmpStructureChecker::Enter(const parser::OpenMPFlushConstruct &x) { PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_flush); } -void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &) { +void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &x) { + if (FindClause(llvm::omp::Clause::OMPC_acquire) || + FindClause(llvm::omp::Clause::OMPC_release) || + FindClause(llvm::omp::Clause::OMPC_acq_rel)) { + if (const auto &flushList{ + std::get<std::optional<parser::OmpObjectList>>(x.t)}) { + context_.Say(parser::FindSourceLocation(flushList), + "If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items " + "must not be specified on the FLUSH directive"_err_en_US); + } + } dirContext_.pop_back(); } diff --git a/flang/test/Semantics/omp-clause-validity01.f90 b/flang/test/Semantics/omp-clause-validity01.f90 index 601e39021e44..3f5345137866 100644 --- a/flang/test/Semantics/omp-clause-validity01.f90 +++ b/flang/test/Semantics/omp-clause-validity01.f90 @@ -487,6 +487,7 @@ use omp_lib !$omp flush acq_rel !$omp flush release !$omp flush acquire + !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive !$omp flush release (c) !ERROR: SEQ_CST clause is not allowed on the FLUSH directive !$omp flush seq_cst diff --git a/flang/test/Semantics/omp-flush01.f90 b/flang/test/Semantics/omp-flush01.f90 new file mode 100644 index 000000000000..cca78e7a09cd --- /dev/null +++ b/flang/test/Semantics/omp-flush01.f90 @@ -0,0 +1,39 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp + +! 2.17.8 Flush construct [OpenMP 5.0] +! memory-order-clause -> +! acq_rel +! release +! acquire +use omp_lib + implicit none + + integer :: i, a, b + real, DIMENSION(10) :: array + + a = 1.0 + !$omp parallel num_threads(4) + !Only memory-order-clauses. + if (omp_get_thread_num() == 1) then + ! Allowed clauses. + !$omp flush acq_rel + array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/) + !$omp flush release + array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/) + !$omp flush acquire + + !ERROR: expected end of line + !ERROR: expected end of line + !$omp flush private(array) + !ERROR: expected end of line + !ERROR: expected end of line + !$omp flush num_threads(4) + + ! Mix allowed and not allowed clauses. + !ERROR: expected end of line + !ERROR: expected end of line + !$omp flush num_threads(4) acquire + end if + !$omp end parallel +end + diff --git a/flang/test/Semantics/omp-flush02.f90 b/flang/test/Semantics/omp-flush02.f90 new file mode 100644 index 000000000000..6e417c49a3b0 --- /dev/null +++ b/flang/test/Semantics/omp-flush02.f90 @@ -0,0 +1,86 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp + +! Check OpenMP 5.0 - 2.17.8 flush Construct +! Restriction - +! If memory-order-clause is release, acquire, or acq_rel, list items must not be specified on the flush directive. + +use omp_lib + implicit none + + TYPE someStruct + REAL :: rr + end TYPE + integer :: i, a, b + real, DIMENSION(10) :: array + TYPE(someStruct) :: structObj + + a = 1.0 + !$omp parallel num_threads(4) + !No list flushes all. + if (omp_get_thread_num() == 1) THEN + !$omp flush + END IF + + array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/) + !Only memory-order-clauses. + if (omp_get_thread_num() == 1) THEN + ! Not allowed clauses. + !ERROR: SEQ_CST clause is not allowed on the FLUSH directive + !$omp flush seq_cst + !ERROR: RELAXED clause is not allowed on the FLUSH directive + !$omp flush relaxed + + ! Not allowed more than once. + !ERROR: At most one ACQ_REL clause can appear on the FLUSH directive + !$omp flush acq_rel acq_rel + !ERROR: At most one RELEASE clause can appear on the FLUSH directive + !$omp flush release release + !ERROR: At most one ACQUIRE clause can appear on the FLUSH directive + !$omp flush acquire acquire + + ! Mix of allowed and not allowed. + !ERROR: SEQ_CST clause is not allowed on the FLUSH directive + !$omp flush seq_cst acquire + END IF + + array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/) + ! No memory-order-clause only list-items. + if (omp_get_thread_num() == 2) THEN + !$omp flush (a) + !$omp flush (i, a, b) + !$omp flush (array, structObj%rr) + ! Too many flush with repeating list items. + !$omp flush (i, a, b, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, b, b, b, b) + !ERROR: No explicit type declared for 'notpresentitem' + !$omp flush (notPresentItem) + END IF + + array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/) + if (omp_get_thread_num() == 3) THEN + !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive + !$omp flush acq_rel (array) + !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive + !$omp flush acq_rel (array, a, i) + + array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/) + !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive + !$omp flush release (array) + !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive + !$omp flush release (array, a) + + array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/) + !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive + !$omp flush acquire (array) + !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive + !$omp flush acquire (array, a, structObj%rr) + END IF + !$omp end parallel + + !$omp parallel num_threads(4) + array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/) + !$omp master + !$omp flush (array) + !$omp end master + !$omp end parallel +end + |