diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 20 | ||||
-rw-r--r-- | test/OpenMP/nesting_of_regions.cpp | 2 |
3 files changed, 19 insertions, 6 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index dacc56f86f..db827a63f8 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -8389,6 +8389,9 @@ def err_omp_argument_type_isdeviceptr : Error < def warn_omp_nesting_simd : Warning< "OpenMP only allows an ordered construct with the simd clause nested in a simd construct">, InGroup<SourceUsesOpenMP>; +def err_omp_orphaned_device_directive : Error< + "orphaned 'omp %0' directives are prohibited" + "; perhaps you forget to enclose the directive into a %select{|||target |teams }1region?">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 14029e20c3..33d10eb9b5 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -3172,6 +3172,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, auto OffendingRegion = ParentRegion; bool NestingProhibited = false; bool CloseNesting = true; + bool OrphanSeen = false; enum { NoRecommend, ShouldBeInParallelRegion, @@ -3213,9 +3214,10 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, } return false; } - // Allow some constructs to be orphaned (they could be used in functions, - // called from OpenMP regions with the required preconditions). - if (ParentRegion == OMPD_unknown) + // Allow some constructs (except teams) to be orphaned (they could be + // used in functions, called from OpenMP regions with the required + // preconditions). + if (ParentRegion == OMPD_unknown && !isOpenMPTeamsDirective(CurrentRegion)) return false; if (CurrentRegion == OMPD_cancellation_point || CurrentRegion == OMPD_cancel) { @@ -3315,6 +3317,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // If specified, a teams construct must be contained within a target // construct. NestingProhibited = ParentRegion != OMPD_target; + OrphanSeen = ParentRegion == OMPD_unknown; Recommend = ShouldBeInTargetRegion; Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); } @@ -3354,9 +3357,14 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, CloseNesting = false; } if (NestingProhibited) { - SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) - << CloseNesting << getOpenMPDirectiveName(OffendingRegion) - << Recommend << getOpenMPDirectiveName(CurrentRegion); + if (OrphanSeen) { + SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) + << getOpenMPDirectiveName(CurrentRegion) << Recommend; + } else { + SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) + << CloseNesting << getOpenMPDirectiveName(OffendingRegion) + << Recommend << getOpenMPDirectiveName(CurrentRegion); + } return true; } } diff --git a/test/OpenMP/nesting_of_regions.cpp b/test/OpenMP/nesting_of_regions.cpp index 13ef64fc27..6c44d94a67 100644 --- a/test/OpenMP/nesting_of_regions.cpp +++ b/test/OpenMP/nesting_of_regions.cpp @@ -3693,6 +3693,8 @@ void foo() { } // TEAMS DIRECTIVE +#pragma omp teams // expected-error {{orphaned 'omp teams' directives are prohibited; perhaps you forget to enclose the directive into a target region?}} + bar(); #pragma omp target #pragma omp teams #pragma omp parallel |