Skip to content

Commit b091b63

Browse files
[clang] Diagnose usages of static methods to define SYCL free function kernels (#18761)
Static class method support will be added after 2025.3 due to impossibility of its implementation with the current approach using integration header. This PR adds diagnostic messages for both static and non-static class methods
1 parent c60a1fc commit b091b63

File tree

7 files changed

+63
-17
lines changed

7 files changed

+63
-17
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9434,8 +9434,6 @@ def err_deleted_inherited_ctor_use : Error<
94349434
def note_called_by : Note<"called by %0">;
94359435
def err_kern_type_not_void_return : Error<
94369436
"kernel function type %0 must have void return type">;
9437-
def err_kern_is_nonstatic_method : Error<
9438-
"kernel function %0 must be a free function or static member function">;
94399437
def err_config_scalar_return : Error<
94409438
"CUDA special function '%0' must have scalar return type">;
94419439
def err_kern_call_not_global_function : Error<
@@ -12930,6 +12928,9 @@ def err_free_function_return_type : Error<
1293012928
"SYCL free function kernel should have return type 'void'">;
1293112929
def err_free_function_first_occurrence_missing_attr: Error<
1293212930
"the first occurrence of SYCL kernel free function should be declared with 'sycl-nd-range-kernel' or 'sycl-single-task-kernel' compile time properties">;
12931+
def err_free_function_class_method : Error<
12932+
"%select{static |}0class method cannot be used to define a SYCL kernel free function kernel">;
12933+
1293312934

1293412935
// SYCL kernel entry point diagnostics
1293512936
def err_sycl_entry_point_invalid : Error<

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5137,8 +5137,8 @@ static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
51375137
}
51385138
if (const auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
51395139
if (Method->isInstance()) {
5140-
S.Diag(Method->getBeginLoc(), diag::err_kern_is_nonstatic_method)
5141-
<< Method;
5140+
S.Diag(Method->getBeginLoc(), diag::err_free_function_class_method)
5141+
<< /*non static*/ 1 << Method;
51425142
return;
51435143
}
51445144
S.Diag(Method->getBeginLoc(), diag::warn_kern_is_method) << Method;

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5835,6 +5835,13 @@ static bool CheckFreeFunctionDiagnostics(Sema &S, FunctionDecl *FD) {
58355835
return S.Diag(FD->getLocation(), diag::err_free_function_return_type);
58365836
}
58375837

5838+
if (const auto *MD = llvm::dyn_cast<CXXMethodDecl>(FD))
5839+
// The free function extension specification usual methods to be used to
5840+
// define a free function kernel. We also disallow static methods because we
5841+
// use integration header.
5842+
return S.Diag(FD->getLocation(), diag::err_free_function_class_method)
5843+
<< !MD->isStatic() << MD->getSourceRange();
5844+
58385845
for (ParmVarDecl *Param : FD->parameters()) {
58395846
if (Param->hasDefaultArg()) {
58405847
return S.Diag(Param->getLocation(),

clang/test/SemaCUDA/bad-attributes.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ __global__ __host__ void z12(); // expected-error {{attributes are not compatib
5151
// expected-note@-1 {{conflicting attribute is here}}
5252

5353
struct S {
54-
__global__ void foo() {}; // expected-error {{must be a free function or static member function}}
54+
__global__ void foo() {}; // expected-error {{class method cannot be used to define a SYCL kernel free function kernel}}
5555
__global__ static void bar(); // expected-warning {{kernel function 'bar' is a member function}}
5656
// Although this is implicitly inline, we shouldn't warn.
5757
__global__ static void baz() {}; // expected-warning {{kernel function 'baz' is a member function}}

clang/test/SemaCUDA/lambda.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public:
4949

5050
int main(void) {
5151
auto lambda_kernel = [&]__global__(){};
52-
// com-error@-1 {{kernel function 'operator()' must be a free function or static member function}}
52+
// com-error@-1 {{class method cannot be used to define a SYCL kernel free function kernel}}
5353

5454
int b;
5555
[&](){ hd(b); }();

clang/test/SemaSYCL/free_function_negative.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,52 @@ singleTaskKernelReturnType(int Value) {
6969
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]] int
7070
ndRangeKernelReturnType(int Value) {
7171
}
72+
73+
class TestClass {
74+
public:
75+
76+
// expected-error@+2 {{class method cannot be used to define a SYCL kernel free function kernel}}
77+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]] void
78+
ndRangeKernelMethod(int Value) {
79+
}
80+
81+
// expected-error@+2 {{class method cannot be used to define a SYCL kernel free function kernel}}
82+
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]] void
83+
singleTaskKernelMethod(int Value) {
84+
}
85+
86+
// expected-error@+2 {{static class method cannot be used to define a SYCL kernel free function kernel}}
87+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
88+
static void StaticndRangeKernelMethod(int Value) {
89+
}
90+
91+
// expected-error@+2 {{static class method cannot be used to define a SYCL kernel free function kernel}}
92+
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]]
93+
static void StaticsingleTaskKernelMethod(int Value) {
94+
}
95+
96+
};
97+
98+
struct TestStruct {
99+
100+
// expected-error@+2 {{class method cannot be used to define a SYCL kernel free function kernel}}
101+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]] void
102+
ndRangeKernelMethod(int Value) {
103+
}
104+
105+
// expected-error@+2 {{class method cannot be used to define a SYCL kernel free function kernel}}
106+
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]] void
107+
singleTaskKernelMethod(int Value) {
108+
}
109+
110+
// expected-error@+2 {{static class method cannot be used to define a SYCL kernel free function kernel}}
111+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
112+
static void StaticndRangeKernelMethod(int Value) {
113+
}
114+
115+
// expected-error@+2 {{static class method cannot be used to define a SYCL kernel free function kernel}}
116+
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]]
117+
static void StaticsingleTaskKernelMethod(int Value) {
118+
}
119+
120+
};

sycl/test/extensions/free_function_kernels/free_function_kernels_diagnostics.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,6 @@ void singleTaskKernelVariadic(...) {}
2727
SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(syclexp::nd_range_kernel<1>)
2828
void ndRangeKernelVariadic(...) {}
2929

30-
class DummyClass {
31-
public:
32-
// Diagnostic for these violations of the restrictions haven't been
33-
// implemented yet.
34-
SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(syclexp::single_task_kernel)
35-
void singleTaskKernelNonStaticMemberFunc(int *Ptr) {}
36-
37-
SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(syclexp::nd_range_kernel<2>)
38-
void ndRangeKernelNonStaticMemberFunc(float *Ptr) {}
39-
};
40-
4130
// expected-error@+2 {{SYCL free function kernel should have return type 'void'}}
4231
SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(syclexp::single_task_kernel)
4332
float singleTaskKernelNonVoid() { return 0.0F; }

0 commit comments

Comments
 (0)