diff options
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 577772301f0..1300de10b29 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -809,7 +809,7 @@ bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, auto DKind = DSAStack->getDirectiveForScope(RSI->TheScope); auto Ty = D->getType(); - if (isOpenMPTargetDirective(DKind)) { + if (isOpenMPTargetExecutionDirective(DKind)) { // This table summarizes how a given variable should be passed to the device // given its type and the clauses where it appears. This table is based on // the description in OpenMP 4.5 [2.10.4, target Construct] and @@ -907,7 +907,7 @@ bool Sema::IsOpenMPCapturedDecl(ValueDecl *D) { DSAStack->hasDirective( [](OpenMPDirectiveKind K, const DeclarationNameInfo &DNI, SourceLocation Loc) -> bool { - return isOpenMPTargetDirective(K); + return isOpenMPTargetExecutionDirective(K); }, false)) { return true; @@ -944,7 +944,8 @@ bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { auto *VD = dyn_cast<VarDecl>(D); return VD && !VD->hasLocalStorage() && - DSAStack->hasExplicitDirective(isOpenMPTargetDirective, Level); + DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, + Level); } void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } @@ -2313,11 +2314,11 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | target | flush | * | // | target | ordered | * | // | target | atomic | * | - // | target | target | * | - // | target | target parallel | * | - // | target | target enter | * | + // | target | target | | + // | target | target parallel | | + // | target | target enter | | // | | data | | - // | target | target exit | * | + // | target | target exit | | // | | data | | // | target | teams | * | // | target | cancellation | | @@ -2347,11 +2348,11 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | target parallel | flush | * | // | target parallel | ordered | * | // | target parallel | atomic | * | - // | target parallel | target | * | - // | target parallel | target parallel | * | - // | target parallel | target enter | * | + // | target parallel | target | | + // | target parallel | target parallel | | + // | target parallel | target enter | | // | | data | | - // | target parallel | target exit | * | + // | target parallel | target exit | | // | | data | | // | target parallel | teams | | // | target parallel | cancellation | | @@ -2498,6 +2499,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // +------------------+-----------------+------------------------------------+ if (Stack->getCurScope()) { auto ParentRegion = Stack->getParentDirective(); + auto OffendingRegion = ParentRegion; bool NestingProhibited = false; bool CloseNesting = true; enum { @@ -2658,10 +2660,30 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, NestingProhibited = !isOpenMPTeamsDirective(ParentRegion); Recommend = ShouldBeInTeamsRegion; } + if (!NestingProhibited && + (isOpenMPTargetExecutionDirective(CurrentRegion) || + isOpenMPTargetDataManagementDirective(CurrentRegion))) { + // OpenMP 4.5 [2.17 Nesting of Regions] + // If a target, target update, target data, target enter data, or + // target exit data construct is encountered during execution of a + // target region, the behavior is unspecified. + NestingProhibited = Stack->hasDirective( + [&OffendingRegion](OpenMPDirectiveKind K, + const DeclarationNameInfo &DNI, + SourceLocation Loc) -> bool { + if (isOpenMPTargetExecutionDirective(K)) { + OffendingRegion = K; + return true; + } else + return false; + }, + false /* don't skip top directive */); + CloseNesting = false; + } if (NestingProhibited) { SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) - << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend - << getOpenMPDirectiveName(CurrentRegion); + << CloseNesting << getOpenMPDirectiveName(OffendingRegion) + << Recommend << getOpenMPDirectiveName(CurrentRegion); return true; } } |