diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -501,7 +501,7 @@ // OpenMP data-mapping attribute OmpMapTo, OmpMapFrom, OmpMapAlloc, OmpMapRelease, OmpMapDelete, // OpenMP miscellaneous flags - OmpCommonBlock, OmpReduction, OmpDeclareSimd, OmpDeclareTarget, + OmpCommonBlock, OmpReduction, OmpAllocate, OmpDeclareSimd, OmpDeclareTarget, OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock, OmpIfSpecified, OmpNone, OmpPreDetermined); using Flags = common::EnumSet; diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -145,6 +145,7 @@ void Enter(const parser::OmpClause::IsDevicePtr &); void Enter(const parser::OmpAlignedClause &); + void Enter(const parser::OmpAllocateClause &); void Enter(const parser::OmpDefaultClause &); void Enter(const parser::OmpDefaultmapClause &); void Enter(const parser::OmpDependClause &); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -544,6 +544,9 @@ } // 2.8.1 TODO: list-item attribute check } +void OmpStructureChecker::Enter(const parser::OmpAllocateClause &) { + CheckAllowed(llvm::omp::Clause::OMPC_allocate); +} void OmpStructureChecker::Enter(const parser::OmpDefaultClause &) { CheckAllowed(llvm::omp::Clause::OMPC_default); } diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -87,10 +87,18 @@ void AddDataSharingAttributeObject(SymbolRef object) { dataSharingAttributeObjects_.insert(object); } + void AddPrivateDataSharingAttributeObject(SymbolRef object) { + privateDataSharingAttributeObjects_.insert(object); + } + void AddAllocateObject(SymbolRef object) { + allocateObjects_.insert(object); + } void ClearDataSharingAttributeObjects() { dataSharingAttributeObjects_.clear(); } bool HasDataSharingAttributeObject(const Symbol &); + bool HasPrivateDataSharingAttributeObject(const Symbol &); + bool HasAllocateObject(const Symbol &); const parser::Name &GetLoopIndex(const parser::DoConstruct &); const parser::DoConstruct *GetDoConstructIf( const parser::ExecutionPartConstruct &); @@ -100,6 +108,8 @@ Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag); SymbolSet dataSharingAttributeObjects_; // on one directive + SymbolSet privateDataSharingAttributeObjects_; + SymbolSet allocateObjects_; SemanticsContext &context_; std::vector dirContext_; // used as a stack }; @@ -254,6 +264,11 @@ ResolveOmpObjectList(x.v, Symbol::Flag::OmpPrivate); return false; } + bool Pre(const parser::OmpAllocateClause &x) { + const auto &objectList{std::get(x.t)}; + ResolveOmpObjectList(objectList, Symbol::Flag::OmpAllocate); + return false; + } bool Pre(const parser::OmpClause::Firstprivate &x) { ResolveOmpObjectList(x.v, Symbol::Flag::OmpFirstPrivate); return false; @@ -273,6 +288,10 @@ Symbol::Flag::OmpFirstPrivate, Symbol::Flag::OmpLastPrivate, Symbol::Flag::OmpReduction, Symbol::Flag::OmpLinear}; + static constexpr Symbol::Flags privateDataSharingAttributeFlags{ + Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate, + Symbol::Flag::OmpLastPrivate}; + static constexpr Symbol::Flags ompFlagsRequireNewSymbol{ Symbol::Flag::OmpPrivate, Symbol::Flag::OmpLinear, Symbol::Flag::OmpFirstPrivate, Symbol::Flag::OmpLastPrivate, @@ -304,6 +323,20 @@ } template +bool DirectiveAttributeVisitor::HasPrivateDataSharingAttributeObject( + const Symbol &object) { + auto it{privateDataSharingAttributeObjects_.find(object)}; + return it != privateDataSharingAttributeObjects_.end(); +} + +template +bool DirectiveAttributeVisitor::HasAllocateObject( + const Symbol &object) { + auto it{allocateObjects_.find(object)}; + return it != allocateObjects_.end(); +} + +template const parser::Name &DirectiveAttributeVisitor::GetLoopIndex( const parser::DoConstruct &x) { using Bounds = parser::LoopControl::Bounds; @@ -846,6 +879,12 @@ } } } + if(HasAllocateObject(*symbol) && !HasPrivateDataSharingAttributeObject(*symbol)){ + context_.Say(name.source, + "The ALLOCATE clause requires that '%s' must appear in a data-sharing " + "attribute clause on the same directive"_err_en_US, + symbol->name()); + } } // within OpenMP construct } @@ -879,6 +918,9 @@ if (dataSharingAttributeFlags.test(ompFlag)) { CheckMultipleAppearances(*name, *symbol, ompFlag); } + if(ompFlag == Symbol::Flag::OmpAllocate){ + AddAllocateObject(*symbol); + } } } else { // Array sections to be changed to substrings as needed @@ -976,6 +1018,9 @@ name.ToString()); } else { AddDataSharingAttributeObject(*target); + if(privateDataSharingAttributeFlags.test(ompFlag)){ + AddPrivateDataSharingAttributeObject(*target); + } } } diff --git a/flang/test/Semantics/omp-clause-validity01.f90 b/flang/test/Semantics/omp-clause-validity01.f90 --- a/flang/test/Semantics/omp-clause-validity01.f90 +++ b/flang/test/Semantics/omp-clause-validity01.f90 @@ -9,7 +9,7 @@ ! TODO: all the internal errors integer :: b = 128 - integer :: c = 32 + integer :: z, c = 32 integer, parameter :: num = 16 real(8) :: arrayA(256), arrayB(512) @@ -45,24 +45,31 @@ enddo !$omp end parallel - !$omp parallel allocate(omp_default_mem_space : b, c) + !$omp parallel private(c, b) allocate(omp_default_mem_space : b, c) do i = 1, N a = 3.14 enddo !$omp end parallel - !$omp parallel allocate(b) allocate(c) + !$omp parallel allocate(b) allocate(c) private(b, c) do i = 1, N a = 3.14 enddo !$omp end parallel - !$omp parallel allocate(xy_alloc :b) + !$omp parallel allocate(xy_alloc :b) private(b) do i = 1, N a = 3.14 enddo !$omp end parallel + !ERROR: ALLOCATE clause is not allowed on the TARGET DATA directive + !$omp target data map(from: b) allocate(b) + do i = 1, N + z = 2 + enddo + !$omp end target data + !ERROR: SCHEDULE clause is not allowed on the PARALLEL directive !$omp parallel schedule(static) do i = 1, N diff --git a/flang/test/Semantics/omp-resolve06.f90 b/flang/test/Semantics/omp-resolve06.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-resolve06.f90 @@ -0,0 +1,20 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +use omp_lib +!2.11.4 Allocate Clause +!For any list item that is specified in the allocate +!clause on a directive, a data-sharing attribute clause +!that may create a private copy of that list item must be +!specified on the same directive. + + integer :: x, N + x = 1 + N = 2 + + + !$omp parallel allocate(omp_default_mem_space : x) + do i = 1, N + !ERROR: The ALLOCATE clause requires that 'x' must appear in a data-sharing attribute clause on the same directive + x = 2 + enddo + !$omp end parallel +end diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -208,7 +208,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause ]; let allowedOnceClauses = [ VersionedClause, @@ -226,7 +226,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause ]; @@ -243,7 +243,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause ]; @@ -265,7 +265,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause ]; } @@ -291,7 +291,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause ]; } def OMP_Section : Directive<"section"> {} @@ -301,7 +301,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause ]; } def OMP_Master : Directive<"master"> {} @@ -363,7 +363,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause ]; let allowedOnceClauses = [ @@ -378,7 +378,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause ]; let allowedOnceClauses = [ VersionedClause, @@ -450,7 +450,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause ]; let allowedOnceClauses = [ @@ -482,7 +482,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause ]; @@ -542,7 +542,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause ]; } @@ -585,7 +585,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause ]; @@ -627,7 +627,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause ]; } def OMP_ParallelSections : Directive<"parallel sections"> { @@ -641,7 +641,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause ]; let allowedOnceClauses = [ VersionedClause @@ -661,7 +661,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -718,7 +718,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause ]; let allowedOnceClauses = [ VersionedClause, @@ -734,7 +734,7 @@ def OMP_TaskLoopSimd : Directive<"taskloop simd"> { let allowedClauses = [ VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -767,7 +767,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause ]; let allowedOnceClauses = [ VersionedClause, @@ -791,7 +791,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause ]; } @@ -837,7 +837,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause ]; @@ -869,7 +869,7 @@ def OMP_DistributeSimd : Directive<"distribute simd"> { let allowedClauses = [ VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -917,7 +917,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause @@ -956,7 +956,7 @@ def OMP_TargetSimd : Directive<"target simd"> { let allowedClauses = [ VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -995,13 +995,13 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause ]; } def OMP_TeamsDistributeSimd : Directive<"teams distribute simd"> { let allowedClauses = [ VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1044,7 +1044,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause ]; @@ -1095,7 +1095,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause ]; } @@ -1107,7 +1107,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause ]; @@ -1134,7 +1134,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause ]; @@ -1157,7 +1157,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause @@ -1197,7 +1197,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause ]; @@ -1262,7 +1262,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause @@ -1309,7 +1309,7 @@ Directive<"target teams distribute simd"> { let allowedClauses = [ VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1364,7 +1364,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause ]; } def OMP_ParallelMasterTaskloop : @@ -1385,7 +1385,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause @@ -1413,7 +1413,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause ]; @@ -1436,7 +1436,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1468,7 +1468,7 @@ def OMP_EndDeclareVariant : Directive<"end declare variant"> {} def OMP_ParallelWorkshare : Directive<"parallel workshare"> { let allowedClauses = [ - VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause,