"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 {
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()) {
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;
// 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'}}
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}}
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