diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 414c18b492816..ce5a799712001 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7060,10 +7060,13 @@ NamedDecl *Sema::ActOnVariableDeclarator( // Static variables declared inside SYCL device code must be const or // constexpr - if (getLangOpts().SYCLIsDevice && SCSpec == DeclSpec::SCS_static && - !R.isConstant(Context)) - SYCLDiagIfDeviceCode(D.getIdentifierLoc(), diag::err_sycl_restrict) - << Sema::KernelNonConstStaticDataVariable; + if (getLangOpts().SYCLIsDevice) { + if (SCSpec == DeclSpec::SCS_static && !R.isConstant(Context)) + SYCLDiagIfDeviceCode(D.getIdentifierLoc(), diag::err_sycl_restrict) + << Sema::KernelNonConstStaticDataVariable; + else if (NewVD->getTSCSpec() == DeclSpec::TSCS_thread_local) + SYCLDiagIfDeviceCode(D.getIdentifierLoc(), diag::err_thread_unsupported); + } switch (D.getDeclSpec().getConstexprSpecifier()) { case CSK_unspecified: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index e7d7b889f6634..6897085a7c6af 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -212,10 +212,16 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef Locs, ObjCInterfaceDecl *ClassReceiver) { if (getLangOpts().SYCLIsDevice) { if (auto VD = dyn_cast(D)) { - if (VD->getStorageClass() == SC_Static && - !VD->getType().isConstant(Context)) + bool IsConst = VD->getType().isConstant(Context); + if (VD->getTLSKind() != VarDecl::TLS_None) + SYCLDiagIfDeviceCode(*Locs.begin(), diag::err_thread_unsupported); + + if (!IsConst && VD->getStorageClass() == SC_Static) SYCLDiagIfDeviceCode(*Locs.begin(), diag::err_sycl_restrict) << Sema::KernelNonConstStaticDataVariable; + else if (!IsConst && VD->hasGlobalStorage() && !isa(VD)) + SYCLDiagIfDeviceCode(*Locs.begin(), diag::err_sycl_restrict) + << Sema::KernelGlobalVariable; } } diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index 26cc8916fae5e..19b77c6760ec1 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -322,14 +322,6 @@ class MarkDeviceFunction : public RecursiveASTVisitor { CheckSYCLType(E->getType(), E->getSourceRange()); if (VarDecl *VD = dyn_cast(D)) { - bool IsConst = VD->getType().getNonReferenceType().isConstQualified(); - if (!IsConst && VD->hasGlobalStorage() && !VD->isStaticLocal() && - !VD->isStaticDataMember() && !isa(VD)) { - if (VD->getTLSKind() != VarDecl::TLS_None) - SemaRef.Diag(E->getLocation(), diag::err_thread_unsupported); - SemaRef.Diag(E->getLocation(), diag::err_sycl_restrict) - << Sema::KernelGlobalVariable; - } if (!VD->isLocalVarDeclOrParm() && VD->hasGlobalStorage()) { VD->addAttr(SYCLDeviceAttr::CreateImplicit(SemaRef.Context)); SemaRef.addSyclDeviceDecl(VD); diff --git a/clang/test/SemaSYCL/prohibit-thread-local.cpp b/clang/test/SemaSYCL/prohibit-thread-local.cpp new file mode 100644 index 0000000000000..0bb2cf3a180e0 --- /dev/null +++ b/clang/test/SemaSYCL/prohibit-thread-local.cpp @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsycl-is-device -verify -fsyntax-only %s + +thread_local const int prohobit_ns_scope = 0; +thread_local int prohobit_ns_scope2 = 0; +thread_local const int allow_ns_scope = 0; + +struct S { + static const thread_local int prohibit_static_member; + static thread_local int prohibit_static_member2; +}; + +struct T { + static const thread_local int allow_static_member; +}; + +void foo() { + // expected-error@+1{{thread-local storage is not supported for the current target}} + thread_local const int prohibit_local = 0; + // expected-error@+1{{thread-local storage is not supported for the current target}} + thread_local int prohibit_local2; +} + +void bar() { thread_local int allow_local; } + +void usage() { + // expected-note@+1 {{called by}} + foo(); + // expected-error@+1 {{thread-local storage is not supported for the current target}} + (void)prohobit_ns_scope; + // expected-error@+2 {{SYCL kernel cannot use a non-const global variable}} + // expected-error@+1 {{thread-local storage is not supported for the current target}} + (void)prohobit_ns_scope2; + // expected-error@+1 {{thread-local storage is not supported for the current target}} + (void)S::prohibit_static_member; + // expected-error@+2 {{SYCL kernel cannot use a non-const static data variable}} + // expected-error@+1 {{thread-local storage is not supported for the current target}} + (void)S::prohibit_static_member2; +} + +template +__attribute__((sycl_kernel)) +// expected-note@+2 2{{called by}} +void +kernel_single_task(Func kernelFunc) { kernelFunc(); } + +int main() { + // expected-note@+1 2{{called by}} + kernel_single_task([]() { usage(); }); + return 0; +} diff --git a/clang/test/SemaSYCL/tls_error.cpp b/clang/test/SemaSYCL/tls_error.cpp index 5f8e14c6d1a76..95284d3512345 100644 --- a/clang/test/SemaSYCL/tls_error.cpp +++ b/clang/test/SemaSYCL/tls_error.cpp @@ -15,10 +15,12 @@ void usage() { template __attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { + //expected-note@+1{{called by}} kernelFunc(); } int main() { + //expected-note@+1{{called by}} kernel_single_task([]() { usage(); }); return 0; }