Skip to content

Commit e064bd5

Browse files
author
Erich Keane
committed
[SYCL] Implement thread-local storage restriction, move vardecl checks
The SYCL spec was recently clarified to prohibit thread local storage, so this commit ensures an error is always emitted in these cases. Additionally, the DeclRefExpr to a VarDecl were switched to delayed diagnostics. Signed-off-by: Erich Keane <[email protected]>
1 parent ba5ffb8 commit e064bd5

File tree

5 files changed

+64
-11
lines changed

5 files changed

+64
-11
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7060,10 +7060,13 @@ NamedDecl *Sema::ActOnVariableDeclarator(
70607060

70617061
// Static variables declared inside SYCL device code must be const or
70627062
// constexpr
7063-
if (getLangOpts().SYCLIsDevice && SCSpec == DeclSpec::SCS_static &&
7064-
!R.isConstant(Context))
7063+
if (getLangOpts().SYCLIsDevice) {
7064+
if (SCSpec == DeclSpec::SCS_static && !R.isConstant(Context))
70657065
SYCLDiagIfDeviceCode(D.getIdentifierLoc(), diag::err_sycl_restrict)
70667066
<< Sema::KernelNonConstStaticDataVariable;
7067+
else if (NewVD->getTSCSpec() == DeclSpec::TSCS_thread_local)
7068+
SYCLDiagIfDeviceCode(D.getIdentifierLoc(), diag::err_thread_unsupported);
7069+
}
70677070

70687071
switch (D.getDeclSpec().getConstexprSpecifier()) {
70697072
case CSK_unspecified:

clang/lib/Sema/SemaExpr.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,17 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
212212
ObjCInterfaceDecl *ClassReceiver) {
213213
if (getLangOpts().SYCLIsDevice) {
214214
if (auto VD = dyn_cast<VarDecl>(D)) {
215+
bool IsConst = VD->getType().isConstant(Context);
216+
if (VD->getTLSKind() != VarDecl::TLS_None)
217+
SYCLDiagIfDeviceCode(*Locs.begin(), diag::err_thread_unsupported);
218+
215219
if (VD->getStorageClass() == SC_Static &&
216-
!VD->getType().isConstant(Context))
220+
!IsConst)
217221
SYCLDiagIfDeviceCode(*Locs.begin(), diag::err_sycl_restrict)
218222
<< Sema::KernelNonConstStaticDataVariable;
223+
else if (VD->hasGlobalStorage() && !isa<ParmVarDecl>(VD) && !IsConst)
224+
SYCLDiagIfDeviceCode(*Locs.begin(), diag::err_sycl_restrict)
225+
<< Sema::KernelGlobalVariable;
219226
}
220227
}
221228

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -322,14 +322,6 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> {
322322

323323
CheckSYCLType(E->getType(), E->getSourceRange());
324324
if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
325-
bool IsConst = VD->getType().getNonReferenceType().isConstQualified();
326-
if (!IsConst && VD->hasGlobalStorage() && !VD->isStaticLocal() &&
327-
!VD->isStaticDataMember() && !isa<ParmVarDecl>(VD)) {
328-
if (VD->getTLSKind() != VarDecl::TLS_None)
329-
SemaRef.Diag(E->getLocation(), diag::err_thread_unsupported);
330-
SemaRef.Diag(E->getLocation(), diag::err_sycl_restrict)
331-
<< Sema::KernelGlobalVariable;
332-
}
333325
if (!VD->isLocalVarDeclOrParm() && VD->hasGlobalStorage()) {
334326
VD->addAttr(SYCLDeviceAttr::CreateImplicit(SemaRef.Context));
335327
SemaRef.addSyclDeviceDecl(VD);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -verify -fsyntax-only -std=c++17 %s
2+
3+
thread_local const int prohobit_ns_scope = 0;
4+
thread_local int prohobit_ns_scope2 = 0;
5+
thread_local const int allow_ns_scope = 0;
6+
7+
struct S {
8+
static const thread_local int prohibit_static_member;
9+
static thread_local int prohibit_static_member2;
10+
};
11+
12+
struct T {
13+
static const thread_local int allow_static_member;
14+
};
15+
16+
void foo() {
17+
// expected-error@+1{{thread-local storage is not supported for the current target}}
18+
thread_local const int prohibit_local = 0;
19+
// expected-error@+1{{thread-local storage is not supported for the current target}}
20+
thread_local int prohibit_local2;
21+
}
22+
23+
void bar() { thread_local int allow_local; }
24+
25+
void usage() {
26+
// expected-note@+1 {{called by}}
27+
foo();
28+
// expected-error@+1 {{thread-local storage is not supported for the current target}}
29+
(void)prohobit_ns_scope;
30+
// expected-error@+2 {{SYCL kernel cannot use a non-const global variable}}
31+
// expected-error@+1 {{thread-local storage is not supported for the current target}}
32+
(void)prohobit_ns_scope2;
33+
// expected-error@+1 {{thread-local storage is not supported for the current target}}
34+
(void)S::prohibit_static_member;
35+
// expected-error@+2 {{SYCL kernel cannot use a non-const static data variable}}
36+
// expected-error@+1 {{thread-local storage is not supported for the current target}}
37+
(void)S::prohibit_static_member2;
38+
}
39+
40+
template <typename name, typename Func>
41+
__attribute__((sycl_kernel))
42+
// expected-note@+1 2{{called by}}
43+
void kernel_single_task(Func kernelFunc) { kernelFunc(); }
44+
45+
int main() {
46+
// expected-note@+1 2{{called by}}
47+
kernel_single_task<class fake_kernel>([](){ usage(); } );
48+
return 0;
49+
}

clang/test/SemaSYCL/tls_error.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ void usage() {
1515

1616
template <typename name, typename Func>
1717
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
18+
//expected-note@+1{{called by}}
1819
kernelFunc();
1920
}
2021

2122
int main() {
23+
//expected-note@+1{{called by}}
2224
kernel_single_task<class fake_kernel>([]() { usage(); });
2325
return 0;
2426
}

0 commit comments

Comments
 (0)