diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index ca8473c6f9674..e39ecc13f4eec 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4501,6 +4501,11 @@ struct OmpToClause { // Ref: [5.0:254-255], [5.1:287-288], [5.2:321-322] // +// In ATOMIC construct +// update-clause -> +// UPDATE // Since 4.5 +// +// In DEPOBJ construct // update-clause -> // UPDATE(dependence-type) // since 5.0, until 5.1 // update-clause -> diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index f1330b8d1909f..c258bef2e4427 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -1400,9 +1400,13 @@ Uniform make(const parser::OmpClause::Uniform &inp, Update make(const parser::OmpClause::Update &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpUpdateClause - auto depType = - common::visit([](auto &&s) { return makeDepType(s); }, inp.v.u); - return Update{/*DependenceType=*/depType}; + if (inp.v) { + return common::visit( + [](auto &&s) { return Update{/*DependenceType=*/makeDepType(s)}; }, + inp.v->u); + } else { + return Update{/*DependenceType=*/std::nullopt}; + } } Use make(const parser::OmpClause::Use &inp, diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index e631922a354c4..bfca4e3f1730a 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -836,9 +836,9 @@ TYPE_PARSER(construct( TYPE_PARSER(construct(Parser{}, maybe(":" >> nonemptyList(Parser{})))) -TYPE_PARSER(construct( - construct(Parser{}) || - construct(Parser{}))) +TYPE_PARSER( // + construct(parenthesized(Parser{})) || + construct(parenthesized(Parser{}))) TYPE_PARSER(construct( maybe(nonemptyList(Parser{}) / ":"), @@ -1079,7 +1079,7 @@ TYPE_PARSER( // parenthesized(nonemptyList(name)))) || "UNTIED" >> construct(construct()) || "UPDATE" >> construct(construct( - parenthesized(Parser{}))) || + maybe(Parser{}))) || "WHEN" >> construct(construct( parenthesized(Parser{}))) || // Cancellable constructs @@ -1313,24 +1313,30 @@ TYPE_PARSER( endOfLine) // Directives enclosing structured-block -TYPE_PARSER(construct(first( - "MASKED" >> pure(llvm::omp::Directive::OMPD_masked), - "MASTER" >> pure(llvm::omp::Directive::OMPD_master), - "ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered), - "PARALLEL MASKED" >> pure(llvm::omp::Directive::OMPD_parallel_masked), - "PARALLEL MASTER" >> pure(llvm::omp::Directive::OMPD_parallel_master), - "PARALLEL WORKSHARE" >> pure(llvm::omp::Directive::OMPD_parallel_workshare), - "PARALLEL" >> pure(llvm::omp::Directive::OMPD_parallel), - "SCOPE" >> pure(llvm::omp::Directive::OMPD_scope), - "SINGLE" >> pure(llvm::omp::Directive::OMPD_single), - "TARGET DATA" >> pure(llvm::omp::Directive::OMPD_target_data), - "TARGET PARALLEL" >> pure(llvm::omp::Directive::OMPD_target_parallel), - "TARGET TEAMS" >> pure(llvm::omp::Directive::OMPD_target_teams), - "TARGET" >> pure(llvm::omp::Directive::OMPD_target), - "TASK"_id >> pure(llvm::omp::Directive::OMPD_task), - "TASKGROUP" >> pure(llvm::omp::Directive::OMPD_taskgroup), - "TEAMS" >> pure(llvm::omp::Directive::OMPD_teams), - "WORKSHARE" >> pure(llvm::omp::Directive::OMPD_workshare)))) +TYPE_PARSER( + // In this context "TARGET UPDATE" can be parsed as a TARGET directive + // followed by an UPDATE clause. This is the only combination at the + // moment, exclude it explicitly. + (!"TARGET UPDATE"_sptok) >= + construct(first( + "MASKED" >> pure(llvm::omp::Directive::OMPD_masked), + "MASTER" >> pure(llvm::omp::Directive::OMPD_master), + "ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered), + "PARALLEL MASKED" >> pure(llvm::omp::Directive::OMPD_parallel_masked), + "PARALLEL MASTER" >> pure(llvm::omp::Directive::OMPD_parallel_master), + "PARALLEL WORKSHARE" >> + pure(llvm::omp::Directive::OMPD_parallel_workshare), + "PARALLEL" >> pure(llvm::omp::Directive::OMPD_parallel), + "SCOPE" >> pure(llvm::omp::Directive::OMPD_scope), + "SINGLE" >> pure(llvm::omp::Directive::OMPD_single), + "TARGET DATA" >> pure(llvm::omp::Directive::OMPD_target_data), + "TARGET PARALLEL" >> pure(llvm::omp::Directive::OMPD_target_parallel), + "TARGET TEAMS" >> pure(llvm::omp::Directive::OMPD_target_teams), + "TARGET" >> pure(llvm::omp::Directive::OMPD_target), + "TASK"_id >> pure(llvm::omp::Directive::OMPD_task), + "TASKGROUP" >> pure(llvm::omp::Directive::OMPD_taskgroup), + "TEAMS" >> pure(llvm::omp::Directive::OMPD_teams), + "WORKSHARE" >> pure(llvm::omp::Directive::OMPD_workshare)))) TYPE_PARSER(sourced(construct( sourced(Parser{}), Parser{}))) diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index d9fe32bae1c27..f654fe6e4681a 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -4571,10 +4571,18 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Update &x) { llvm::omp::Directive dir{GetContext().directive}; unsigned version{context_.langOptions().OpenMPVersion}; - auto *depType{std::get_if(&x.v.u)}; - auto *taskType{std::get_if(&x.v.u)}; - assert(((depType == nullptr) != (taskType == nullptr)) && - "Unexpected alternative in update clause"); + const parser::OmpDependenceType *depType{nullptr}; + const parser::OmpTaskDependenceType *taskType{nullptr}; + if (auto &maybeUpdate{x.v}) { + depType = std::get_if(&maybeUpdate->u); + taskType = std::get_if(&maybeUpdate->u); + } + + if (!depType && !taskType) { + assert(dir == llvm::omp::Directive::OMPD_atomic && + "Unexpected alternative in update clause"); + return; + } if (depType) { CheckDependenceType(depType->v); diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index cdfd3e3223fa8..f4e400b651c31 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -525,6 +525,7 @@ def OMPC_Untied : Clause<"untied"> { def OMPC_Update : Clause<"update"> { let clangClass = "OMPUpdateClause"; let flangClass = "OmpUpdateClause"; + let isValueOptional = true; } def OMPC_Use : Clause<"use"> { let clangClass = "OMPUseClause";