Skip to content

Commit 1b9f026

Browse files
authored
[SYCL] Error for implicit capture of this pointer inside a sycl kernel (#2029)
Signed-off-by: Arvind Sudarsanam <[email protected]>
1 parent 400e1e6 commit 1b9f026

File tree

4 files changed

+45
-12
lines changed

4 files changed

+45
-12
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

+2
Original file line numberDiff line numberDiff line change
@@ -7326,6 +7326,8 @@ let CategoryName = "Lambda Issue" in {
73267326
"here">;
73277327
def note_var_explicitly_captured_here : Note<"variable %0 is"
73287328
"%select{| explicitly}1 captured here">;
7329+
def err_implicit_this_capture : Error<
7330+
"implicit capture of 'this' is not allowed for kernel functions">;
73297331

73307332
// C++14 lambda init-captures.
73317333
def warn_cxx11_compat_init_capture : Warning<

clang/lib/Sema/SemaSYCL.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -1944,6 +1944,11 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
19441944
constructKernelName(*this, KernelCallerFunc, MC);
19451945
StringRef KernelName(getLangOpts().SYCLUnnamedLambda ? StableName
19461946
: CalculatedName);
1947+
if (KernelObj->isLambda()) {
1948+
for (const LambdaCapture &LC : KernelObj->captures())
1949+
if (LC.capturesThis() && LC.isImplicit())
1950+
Diag(LC.getLocation(), diag::err_implicit_this_capture);
1951+
}
19471952
SyclKernelFieldChecker checker(*this);
19481953
SyclKernelDeclCreator kernel_decl(
19491954
*this, checker, KernelName, KernelObj->getLocation(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_cc1 -I %S/Inputs -fsycl -fsycl-is-device -fsyntax-only -verify %s
2+
3+
template <typename name, typename Func>
4+
__attribute__((sycl_kernel)) void kernel(Func kernelFunc) {
5+
kernelFunc();
6+
}
7+
8+
class Class {
9+
public:
10+
Class() : member(1) {}
11+
void function();
12+
int member;
13+
};
14+
15+
void Class::function() {
16+
kernel<class kernel_wrapper>(
17+
[=]() {
18+
int acc[1] = {5};
19+
acc[0] *= member; // expected-error{{implicit capture of 'this' is not allowed for kernel functions}}
20+
});
21+
}
22+
23+
int main(int argc, char *argv[]) {
24+
Class c;
25+
c.function();
26+
}

sycl/include/CL/sycl/handler.hpp

+12-12
Original file line numberDiff line numberDiff line change
@@ -509,8 +509,8 @@ class __SYCL_EXPORT handler {
509509

510510
template <typename T, int Dim, access::mode Mode, access::target Target,
511511
access::placeholder IsPH>
512-
detail::enable_if_t<Dim == 0 && Mode == access::mode::atomic, T>
513-
readFromFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Src) const {
512+
static detail::enable_if_t<Dim == 0 && Mode == access::mode::atomic, T>
513+
readFromFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Src) {
514514
#ifdef __ENABLE_USM_ADDR_SPACE__
515515
atomic<T, access::address_space::global_device_space> AtomicSrc = Src;
516516
#else
@@ -521,23 +521,23 @@ class __SYCL_EXPORT handler {
521521

522522
template <typename T, int Dim, access::mode Mode, access::target Target,
523523
access::placeholder IsPH>
524-
detail::enable_if_t<(Dim > 0) && Mode == access::mode::atomic, T>
525-
readFromFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Src) const {
524+
static detail::enable_if_t<(Dim > 0) && Mode == access::mode::atomic, T>
525+
readFromFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Src) {
526526
id<Dim> Id = getDelinearizedIndex(Src.get_range(), 0);
527527
return Src[Id].load();
528528
}
529529

530530
template <typename T, int Dim, access::mode Mode, access::target Target,
531531
access::placeholder IsPH>
532-
detail::enable_if_t<Mode != access::mode::atomic, T>
533-
readFromFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Src) const {
532+
static detail::enable_if_t<Mode != access::mode::atomic, T>
533+
readFromFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Src) {
534534
return *(Src.get_pointer());
535535
}
536536

537537
template <typename T, int Dim, access::mode Mode, access::target Target,
538538
access::placeholder IsPH>
539-
detail::enable_if_t<Dim == 0 && Mode == access::mode::atomic, void>
540-
writeToFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Dst, T V) const {
539+
static detail::enable_if_t<Dim == 0 && Mode == access::mode::atomic, void>
540+
writeToFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Dst, T V) {
541541
#ifdef __ENABLE_USM_ADDR_SPACE__
542542
atomic<T, access::address_space::global_device_space> AtomicDst = Dst;
543543
#else
@@ -548,16 +548,16 @@ class __SYCL_EXPORT handler {
548548

549549
template <typename T, int Dim, access::mode Mode, access::target Target,
550550
access::placeholder IsPH>
551-
detail::enable_if_t<(Dim > 0) && Mode == access::mode::atomic, void>
552-
writeToFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Dst, T V) const {
551+
static detail::enable_if_t<(Dim > 0) && Mode == access::mode::atomic, void>
552+
writeToFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Dst, T V) {
553553
id<Dim> Id = getDelinearizedIndex(Dst.get_range(), 0);
554554
Dst[Id].store(V);
555555
}
556556

557557
template <typename T, int Dim, access::mode Mode, access::target Target,
558558
access::placeholder IsPH>
559-
detail::enable_if_t<Mode != access::mode::atomic, void>
560-
writeToFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Dst, T V) const {
559+
static detail::enable_if_t<Mode != access::mode::atomic, void>
560+
writeToFirstAccElement(accessor<T, Dim, Mode, Target, IsPH> Dst, T V) {
561561
*(Dst.get_pointer()) = V;
562562
}
563563

0 commit comments

Comments
 (0)