From 2b51f7284b293f4cda9ba2368e9a93dc98604ed7 Mon Sep 17 00:00:00 2001 From: Kelvin Li Date: Tue, 26 Jul 2016 04:32:50 +0000 Subject: [PATCH] [OpenMP] diagnose orphaned teams construct The OpenMP spec mandates that 'a teams construct must be contained within a target construct'. Currently, this scenario is not diagnosed. This patch is to add check for orphaned teams construct and issue an error message. Differential Revision: https://reviews.llvm.org/D22785 llvm-svn: 276726 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 +++ clang/lib/Sema/SemaOpenMP.cpp | 20 ++++++++++++++------ clang/test/OpenMP/nesting_of_regions.cpp | 2 ++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index dacc56f..db827a6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/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; +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/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 14029e2..33d10eb 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/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/clang/test/OpenMP/nesting_of_regions.cpp b/clang/test/OpenMP/nesting_of_regions.cpp index 13ef64f..6c44d94 100644 --- a/clang/test/OpenMP/nesting_of_regions.cpp +++ b/clang/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 -- 2.7.4