From ca35ec3b391ab9e6131d973cfe72870a13394df2 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Fri, 16 Aug 2019 20:15:02 +0000 Subject: [PATCH] [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 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaOpenMP.cpp | 26 ++++++++++++++++++++-- test/OpenMP/declare_target_messages.cpp | 17 ++++++++------ 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 68af72ba66..2abb43c458 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -9318,6 +9318,8 @@ def err_omp_wrong_dependency_iterator_type : Error< "expected an integer or a pointer type of the outer loop counter '%0' for non-rectangular nests">; def err_omp_unsupported_type : Error < "host requires %0 bit size %1 type support, but device '%2' does not support it">; +def omp_lambda_capture_in_declare_target_not_to : Error< + "variable captured in declare target region must appear in a to clause">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { 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(D)) return; auto *VD = cast(D); - if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) + Optional MapTy = + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); + if (SemaRef.LangOpts.OpenMP >= 50 && + (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || + SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && + VD->hasGlobalStorage()) { + llvm::Optional 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; diff --git a/test/OpenMP/declare_target_messages.cpp b/test/OpenMP/declare_target_messages.cpp index 642d3e8727..fb5bd34c4a 100644 --- a/test/OpenMP/declare_target_messages.cpp +++ b/test/OpenMP/declare_target_messages.cpp @@ -1,10 +1,11 @@ // RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -fnoopenmp-use-tls -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -fnoopenmp-use-tls -ferror-limit 100 -o - %s // RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp-simd -fnoopenmp-use-tls -ferror-limit 100 -o - %s #pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} -int a, b; +int a, b, z; // omp5-error {{variable captured in declare target region must appear in a to clause}} __thread int t; // expected-note {{defined as threadprivate or thread local}} #pragma omp declare target . // expected-error {{expected '(' after 'declare target'}} @@ -65,11 +66,11 @@ void t2() { void cba(); #pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} -#pragma omp declare target - #pragma omp declare target - void def(); - #pragma omp end declare target - void fed(); +#pragma omp declare target +#pragma omp declare target +void def(); +#pragma omp end declare target +void fed(); #pragma omp declare target #pragma omp threadprivate(a) // expected-note {{defined as threadprivate or thread local}} @@ -112,7 +113,9 @@ void foo(int p) { c(); } #pragma omp declare target -void foo1() {} +void foo1() { + [&](){ (void)(b+z);}(); // omp5-note {{variable 'z' is captured here}} +} #pragma omp end declare target #pragma omp end declare target -- 2.40.0