diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index d7a0681d1c3d4..1b6b38d0e972d 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -919,12 +919,28 @@ void OmpStructureChecker::ChecksOnOrderedAsBlock() { } } +void OmpStructureChecker::CheckTargetData() { + const parser::OmpClause *mapClause = FindClause(llvm::omp::Clause::OMPC_map); + const parser::OmpClause *useDevicePtrClause = + FindClause(llvm::omp::Clause::OMPC_use_device_ptr); + const parser::OmpClause *useDeviceAddrClause = + FindClause(llvm::omp::OMPC_use_device_addr); + if (!mapClause && !useDevicePtrClause && !useDeviceAddrClause) { + context_.Say(GetContext().directiveSource, + "At least one MAP, USE_DEVICE_ADDR or USE_DEVICE_PTR clause must " + "appear on the TARGET DATA directive."_err_en_US); + } +} + void OmpStructureChecker::Leave(const parser::OmpBeginBlockDirective &) { switch (GetContext().directive) { case llvm::omp::Directive::OMPD_ordered: // [5.1] 2.19.9 Ordered Construct Restriction ChecksOnOrderedAsBlock(); break; + case llvm::omp::Directive::OMPD_target_data: + CheckTargetData(); + return; default: break; } diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index d35602cca75d5..5c80c1ea8a2d2 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -184,6 +184,7 @@ class OmpStructureChecker void CheckSIMDNest(const parser::OpenMPConstruct &x); void CheckTargetNest(const parser::OpenMPConstruct &x); void CheckTargetUpdate(); + void CheckTargetData(); void CheckCancellationNest( const parser::CharBlock &source, const parser::OmpCancelType::Type &type); std::int64_t GetOrdCollapseLevel(const parser::OpenMPLoopConstruct &x); diff --git a/flang/test/Semantics/OpenMP/device-constructs.f90 b/flang/test/Semantics/OpenMP/device-constructs.f90 index 51f00700b6daf..a18d99d7c368b 100644 --- a/flang/test/Semantics/OpenMP/device-constructs.f90 +++ b/flang/test/Semantics/OpenMP/device-constructs.f90 @@ -135,7 +135,7 @@ program main enddo !$omp end target data - !ERROR: At least one of MAP clause must appear on the TARGET DATA directive + !ERROR: At least one MAP, USE_DEVICE_ADDR or USE_DEVICE_PTR clause must appear on the TARGET DATA directive. !$omp target data device(0) do i = 1, N a = 3.14 diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index f8b3b0c752497..79211976c0270 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -705,15 +705,13 @@ def OMP_Nothing : Directive<"nothing"> {} def OMP_TargetData : Directive<"target data"> { let allowedClauses = [ VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; let allowedOnceClauses = [ VersionedClause, VersionedClause ]; - let requiredClauses = [ - VersionedClause - ]; } def OMP_TargetEnterData : Directive<"target enter data"> { let allowedClauses = [