@@ -4797,6 +4797,12 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4797
4797
ShouldBeInTeamsRegion,
4798
4798
ShouldBeInLoopSimdRegion,
4799
4799
} Recommend = NoRecommend;
4800
+
4801
+ SmallVector<OpenMPDirectiveKind, 4> LeafOrComposite;
4802
+ ArrayRef<OpenMPDirectiveKind> ParentLOC =
4803
+ getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite);
4804
+ OpenMPDirectiveKind EnclosingConstruct = ParentLOC.back();
4805
+
4800
4806
if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
4801
4807
CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
4802
4808
CurrentRegion != OMPD_parallel &&
@@ -4828,7 +4834,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4828
4834
<< (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4829
4835
return CurrentRegion != OMPD_simd;
4830
4836
}
4831
- if (ParentRegion == OMPD_atomic) {
4837
+ if (EnclosingConstruct == OMPD_atomic) {
4832
4838
// OpenMP [2.16, Nesting of Regions]
4833
4839
// OpenMP constructs may not be nested inside an atomic region.
4834
4840
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
@@ -4839,8 +4845,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4839
4845
// Orphaned section directives are prohibited. That is, the section
4840
4846
// directives must appear within the sections construct and must not be
4841
4847
// encountered elsewhere in the sections region.
4842
- if (ParentRegion != OMPD_sections &&
4843
- ParentRegion != OMPD_parallel_sections) {
4848
+ if (EnclosingConstruct != OMPD_sections) {
4844
4849
SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4845
4850
<< (ParentRegion != OMPD_unknown)
4846
4851
<< getOpenMPDirectiveName(ParentRegion);
@@ -4861,7 +4866,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4861
4866
if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
4862
4867
(BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) &&
4863
4868
(isOpenMPWorksharingDirective(ParentRegion) ||
4864
- ParentRegion == OMPD_loop)) {
4869
+ EnclosingConstruct == OMPD_loop)) {
4865
4870
int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
4866
4871
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4867
4872
<< true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
@@ -4881,27 +4886,17 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4881
4886
// construct-type-clause is not taskgroup must be closely nested inside an
4882
4887
// OpenMP construct that matches the type specified in
4883
4888
// construct-type-clause.
4884
- NestingProhibited =
4885
- !((CancelRegion == OMPD_parallel &&
4886
- (ParentRegion == OMPD_parallel ||
4887
- ParentRegion == OMPD_target_parallel)) ||
4888
- (CancelRegion == OMPD_for &&
4889
- (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4890
- ParentRegion == OMPD_target_parallel_for ||
4891
- ParentRegion == OMPD_distribute_parallel_for ||
4892
- ParentRegion == OMPD_teams_distribute_parallel_for ||
4893
- ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4894
- (CancelRegion == OMPD_taskgroup &&
4895
- (ParentRegion == OMPD_task ||
4896
- (SemaRef.getLangOpts().OpenMP >= 50 &&
4897
- (ParentRegion == OMPD_taskloop ||
4898
- ParentRegion == OMPD_master_taskloop ||
4899
- ParentRegion == OMPD_masked_taskloop ||
4900
- ParentRegion == OMPD_parallel_masked_taskloop ||
4901
- ParentRegion == OMPD_parallel_master_taskloop)))) ||
4902
- (CancelRegion == OMPD_sections &&
4903
- (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4904
- ParentRegion == OMPD_parallel_sections)));
4889
+ ArrayRef<OpenMPDirectiveKind> Leafs = getLeafConstructsOrSelf(ParentRegion);
4890
+ if (CancelRegion == OMPD_taskgroup) {
4891
+ NestingProhibited = EnclosingConstruct != OMPD_task &&
4892
+ (SemaRef.getLangOpts().OpenMP < 50 ||
4893
+ EnclosingConstruct != OMPD_taskloop);
4894
+ } else if (CancelRegion == OMPD_sections) {
4895
+ NestingProhibited = EnclosingConstruct != OMPD_section &&
4896
+ EnclosingConstruct != OMPD_sections;
4897
+ } else {
4898
+ NestingProhibited = CancelRegion != Leafs.back();
4899
+ }
4905
4900
OrphanSeen = ParentRegion == OMPD_unknown;
4906
4901
} else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4907
4902
// OpenMP 5.1 [2.22, Nesting of Regions]
@@ -4942,27 +4937,25 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4942
4937
// OpenMP 5.1 [2.22, Nesting of Regions]
4943
4938
// A barrier region may not be closely nested inside a worksharing, loop,
4944
4939
// task, taskloop, critical, ordered, atomic, or masked region.
4945
- NestingProhibited =
4946
- isOpenMPWorksharingDirective(ParentRegion) ||
4947
- isOpenMPGenericLoopDirective(ParentRegion) ||
4948
- isOpenMPTaskingDirective(ParentRegion) || ParentRegion == OMPD_master ||
4949
- ParentRegion == OMPD_masked || ParentRegion == OMPD_parallel_master ||
4950
- ParentRegion == OMPD_parallel_masked || ParentRegion == OMPD_critical ||
4951
- ParentRegion == OMPD_ordered;
4940
+ NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4941
+ isOpenMPGenericLoopDirective(ParentRegion) ||
4942
+ isOpenMPTaskingDirective(ParentRegion) ||
4943
+ llvm::is_contained({OMPD_masked, OMPD_master,
4944
+ OMPD_critical, OMPD_ordered},
4945
+ EnclosingConstruct);
4952
4946
} else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4953
4947
!isOpenMPParallelDirective(CurrentRegion) &&
4954
4948
!isOpenMPTeamsDirective(CurrentRegion)) {
4955
4949
// OpenMP 5.1 [2.22, Nesting of Regions]
4956
4950
// A loop region that binds to a parallel region or a worksharing region
4957
4951
// may not be closely nested inside a worksharing, loop, task, taskloop,
4958
4952
// critical, ordered, atomic, or masked region.
4959
- NestingProhibited =
4960
- isOpenMPWorksharingDirective(ParentRegion) ||
4961
- isOpenMPGenericLoopDirective(ParentRegion) ||
4962
- isOpenMPTaskingDirective(ParentRegion) || ParentRegion == OMPD_master ||
4963
- ParentRegion == OMPD_masked || ParentRegion == OMPD_parallel_master ||
4964
- ParentRegion == OMPD_parallel_masked || ParentRegion == OMPD_critical ||
4965
- ParentRegion == OMPD_ordered;
4953
+ NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4954
+ isOpenMPGenericLoopDirective(ParentRegion) ||
4955
+ isOpenMPTaskingDirective(ParentRegion) ||
4956
+ llvm::is_contained({OMPD_masked, OMPD_master,
4957
+ OMPD_critical, OMPD_ordered},
4958
+ EnclosingConstruct);
4966
4959
Recommend = ShouldBeInParallelRegion;
4967
4960
} else if (CurrentRegion == OMPD_ordered) {
4968
4961
// OpenMP [2.16, Nesting of Regions]
@@ -4973,7 +4966,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4973
4966
// OpenMP [2.8.1,simd Construct, Restrictions]
4974
4967
// An ordered construct with the simd clause is the only OpenMP construct
4975
4968
// that can appear in the simd region.
4976
- NestingProhibited = ParentRegion == OMPD_critical ||
4969
+ NestingProhibited = EnclosingConstruct == OMPD_critical ||
4977
4970
isOpenMPTaskingDirective(ParentRegion) ||
4978
4971
!(isOpenMPSimdDirective(ParentRegion) ||
4979
4972
Stack->isParentOrderedRegion());
@@ -4983,22 +4976,19 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4983
4976
// If specified, a teams construct must be contained within a target
4984
4977
// construct.
4985
4978
NestingProhibited =
4986
- (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4987
- (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4988
- ParentRegion != OMPD_target);
4979
+ (SemaRef.LangOpts.OpenMP <= 45 && EnclosingConstruct != OMPD_target) ||
4980
+ (SemaRef.LangOpts.OpenMP >= 50 && EnclosingConstruct != OMPD_unknown &&
4981
+ EnclosingConstruct != OMPD_target);
4989
4982
OrphanSeen = ParentRegion == OMPD_unknown;
4990
4983
Recommend = ShouldBeInTargetRegion;
4991
4984
} else if (CurrentRegion == OMPD_scan) {
4992
4985
if (SemaRef.LangOpts.OpenMP >= 50) {
4993
- SmallVector<OpenMPDirectiveKind, 4> LeafOrComposite;
4994
- std::ignore = getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite);
4995
4986
// OpenMP spec 5.0 and 5.1 require scan to be directly enclosed by for,
4996
4987
// simd, or for simd. This has to take into account combined directives.
4997
4988
// In 5.2 this seems to be implied by the fact that the specified
4998
4989
// separated constructs are do, for, and simd.
4999
- OpenMPDirectiveKind Enclosing = LeafOrComposite.back();
5000
- NestingProhibited = Enclosing != OMPD_for && Enclosing != OMPD_simd &&
5001
- Enclosing != OMPD_for_simd;
4990
+ NestingProhibited = !llvm::is_contained(
4991
+ {OMPD_for, OMPD_simd, OMPD_for_simd}, EnclosingConstruct);
5002
4992
} else {
5003
4993
NestingProhibited = true;
5004
4994
}
@@ -5007,7 +4997,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
5007
4997
}
5008
4998
if (!NestingProhibited && !isOpenMPTargetExecutionDirective(CurrentRegion) &&
5009
4999
!isOpenMPTargetDataManagementDirective(CurrentRegion) &&
5010
- (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams) ) {
5000
+ EnclosingConstruct == OMPD_teams) {
5011
5001
// OpenMP [5.1, 2.22, Nesting of Regions]
5012
5002
// distribute, distribute simd, distribute parallel worksharing-loop,
5013
5003
// distribute parallel worksharing-loop SIMD, loop, parallel regions,
@@ -5029,17 +5019,15 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
5029
5019
// If the bind clause is present on the loop construct and binding is
5030
5020
// teams then the corresponding loop region must be strictly nested inside
5031
5021
// a teams region.
5032
- NestingProhibited = BindKind == OMPC_BIND_teams &&
5033
- ParentRegion != OMPD_teams &&
5034
- ParentRegion != OMPD_target_teams;
5022
+ NestingProhibited =
5023
+ BindKind == OMPC_BIND_teams && EnclosingConstruct != OMPD_teams;
5035
5024
Recommend = ShouldBeInTeamsRegion;
5036
5025
}
5037
5026
if (!NestingProhibited && isOpenMPNestingDistributeDirective(CurrentRegion)) {
5038
5027
// OpenMP 4.5 [2.17 Nesting of Regions]
5039
5028
// The region associated with the distribute construct must be strictly
5040
5029
// nested inside a teams region
5041
- NestingProhibited =
5042
- (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5030
+ NestingProhibited = EnclosingConstruct != OMPD_teams;
5043
5031
Recommend = ShouldBeInTeamsRegion;
5044
5032
}
5045
5033
if (!NestingProhibited &&
0 commit comments