diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2019-08-16 20:15:02 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2019-08-16 20:15:02 +0000 |
commit | ca35ec3b391ab9e6131d973cfe72870a13394df2 (patch) | |
tree | d417789db62031567d3aa5395de22aa19ee42d06 /lib/Sema | |
parent | 4eeccf9ca40353f027441033bf35ddef2748ac40 (diff) | |
download | clang-ca35ec3b391ab9e6131d973cfe72870a13394df2.tar.gz |
[OPENMP5.0]Diagnose global variables in lambda not marked as declare
target.
According to OpenMP 5.0, if a lambda declaration and definition appears between a declare target directive and the matching end declare target directive, all variables that are captured by the lambda expression must also appear in a to clause.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@369146 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 79d9561c07..bba116e481 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -1796,7 +1796,8 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, if (isInOpenMPDeclareTargetContext()) { // Try to mark variable as declare target if it is used in capturing // regions. - if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) + if (LangOpts.OpenMP <= 45 && + !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) checkDeclIsAllowedInOpenMPTarget(nullptr, VD); return nullptr; } else if (isInOpenMPTargetExecutionDirective()) { @@ -15349,7 +15350,28 @@ static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, if (!D || !isa<VarDecl>(D)) return; auto *VD = cast<VarDecl>(D); - if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) + Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); + if (SemaRef.LangOpts.OpenMP >= 50 && + (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || + SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && + VD->hasGlobalStorage()) { + llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); + if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { + // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions + // If a lambda declaration and definition appears between a + // declare target directive and the matching end declare target + // directive, all variables that are captured by the lambda + // expression must also appear in a to clause. + SemaRef.Diag(VD->getLocation(), + diag::omp_lambda_capture_in_declare_target_not_to); + SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) + << VD << 0 << SR; + return; + } + } + if (MapTy.hasValue()) return; SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); SemaRef.Diag(SL, diag::note_used_here) << SR; |