Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -8389,6 +8389,9 @@ def warn_omp_nesting_simd : Warning< "OpenMP only allows an ordered construct with the simd clause nested in a simd construct">, InGroup; +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 { Index: cfe/trunk/lib/Sema/SemaOpenMP.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaOpenMP.cpp +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp @@ -3172,6 +3172,7 @@ auto OffendingRegion = ParentRegion; bool NestingProhibited = false; bool CloseNesting = true; + bool OrphanSeen = false; enum { NoRecommend, ShouldBeInParallelRegion, @@ -3213,9 +3214,10 @@ } 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 @@ // 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 @@ 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; } } Index: cfe/trunk/test/OpenMP/nesting_of_regions.cpp =================================================================== --- cfe/trunk/test/OpenMP/nesting_of_regions.cpp +++ cfe/trunk/test/OpenMP/nesting_of_regions.cpp @@ -3693,6 +3693,8 @@ } // 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