Skip to content

Commit 5512617

Browse files
[SYCL] add clang diagnostic for kernel free function (#18329)
1. Kernel free function should not support arguments with default values according to [docs](https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/proposed/sycl_ext_oneapi_free_function_kernels.asciidoc#defining-a-free-function-kernel). 2. Kernel free function should have return type void only, diagnostic message was added to clarify that. PR adds diagnostic messages for this cases.
1 parent 936881a commit 5512617

File tree

4 files changed

+56
-20
lines changed

4 files changed

+56
-20
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

+6-1
Original file line numberDiff line numberDiff line change
@@ -12670,8 +12670,13 @@ def err_registered_kernels_name_already_registered : Error<
1267012670
"free function kernel has already been registered with '%0'; cannot register with '%1'">;
1267112671
def err_not_sycl_free_function : Error<
1267212672
"attempting to register a function that is not a SYCL free function as '%0'">;
12673-
def err_free_function_variadic_args: Error<
12673+
def err_free_function_with_default_arg : Error<
12674+
"a function with a default argument value cannot be used to define SYCL free function kernel">;
12675+
def err_free_function_variadic_args : Error<
1267412676
"free function kernel cannot be a variadic function">;
12677+
def err_free_function_return_type : Error<
12678+
"SYCL free function kernel should have return type 'void'">;
12679+
1267512680

1267612681
// SYCL kernel entry point diagnostics
1267712682
def err_sycl_entry_point_invalid : Error<

clang/lib/Sema/SemaSYCL.cpp

+20-11
Original file line numberDiff line numberDiff line change
@@ -1159,21 +1159,13 @@ static target getAccessTarget(QualType FieldTy,
11591159
AccTy->getTemplateArgs()[3].getAsIntegral().getExtValue());
11601160
}
11611161

1162-
// FIXME: Free functions must have void return type and be declared at file
1163-
// scope, outside any namespaces.
11641162
bool SemaSYCL::isFreeFunction(const FunctionDecl *FD) {
11651163
for (auto *IRAttr : FD->specific_attrs<SYCLAddIRAttributesFunctionAttr>()) {
11661164
SmallVector<std::pair<std::string, std::string>, 4> NameValuePairs =
11671165
IRAttr->getAttributeNameValuePairs(getASTContext());
11681166
for (const auto &NameValuePair : NameValuePairs) {
11691167
if (NameValuePair.first == "sycl-nd-range-kernel" ||
11701168
NameValuePair.first == "sycl-single-task-kernel") {
1171-
if (!FD->getReturnType()->isVoidType()) {
1172-
llvm::report_fatal_error(
1173-
"Only functions at file scope with void return "
1174-
"type are permitted as free functions");
1175-
return false;
1176-
}
11771169
return true;
11781170
}
11791171
}
@@ -5791,12 +5783,29 @@ void SemaSYCL::MarkDevices() {
57915783
}
57925784
}
57935785

5786+
static bool CheckFreeFunctionDiagnostics(Sema &S, FunctionDecl *FD) {
5787+
if (FD->isVariadic()) {
5788+
return S.Diag(FD->getLocation(), diag::err_free_function_variadic_args);
5789+
}
5790+
5791+
if (!FD->getReturnType()->isVoidType()) {
5792+
return S.Diag(FD->getLocation(), diag::err_free_function_return_type);
5793+
}
5794+
5795+
for (ParmVarDecl *Param : FD->parameters()) {
5796+
if (Param->hasDefaultArg()) {
5797+
return S.Diag(Param->getLocation(),
5798+
diag::err_free_function_with_default_arg)
5799+
<< Param->getSourceRange();
5800+
}
5801+
}
5802+
return false;
5803+
}
5804+
57945805
void SemaSYCL::ProcessFreeFunction(FunctionDecl *FD) {
57955806
if (isFreeFunction(FD)) {
5796-
if (FD->isVariadic()) {
5797-
Diag(FD->getLocation(), diag::err_free_function_variadic_args);
5807+
if (CheckFreeFunctionDiagnostics(SemaRef, FD))
57985808
return;
5799-
}
58005809
SyclKernelDecompMarker DecompMarker(*this);
58015810
SyclKernelFieldChecker FieldChecker(*this);
58025811
SyclKernelUnionChecker UnionChecker(*this);

clang/test/SemaSYCL/free_function_negative.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,33 @@ foo(int start, ...) { // expected-error {{free function kernel cannot be a varia
99
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]] void
1010
foo1(int start, ...) { // expected-error {{free function kernel cannot be a variadic function}}
1111
}
12+
13+
// expected-error@+2 {{a function with a default argument value cannot be used to define SYCL free function kernel}}
14+
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]] void
15+
singleTaskKernelDefaultValues(int Value = 1) {
16+
}
17+
18+
// expected-error@+2 {{a function with a default argument value cannot be used to define SYCL free function kernel}}
19+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]] void
20+
ndRangeKernelDefaultValues(int Value = 1) {
21+
}
22+
23+
// expected-error@+2 {{a function with a default argument value cannot be used to define SYCL free function kernel}}
24+
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]] void
25+
singleTaskKernelDefaultValues(int Ivalue = 1, unsigned int Uvalue = 3) {
26+
}
27+
28+
// expected-error@+2 {{a function with a default argument value cannot be used to define SYCL free function kernel}}
29+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]] void
30+
ndRangeKernelDefaultValues(int Ivalue = 1, unsigned int Uvalue = 3) {
31+
}
32+
33+
// expected-error@+2 {{SYCL free function kernel should have return type 'void'}}
34+
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]] int
35+
singleTaskKernelReturnType(int Value) {
36+
}
37+
38+
// expected-error@+2 {{SYCL free function kernel should have return type 'void'}}
39+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]] int
40+
ndRangeKernelReturnType(int Value) {
41+
}

sycl/test/extensions/free_function_kernels/free_function_kernels_diagnostics.cpp

-8
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,3 @@ SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(syclexp::single_task_kernel)
1818
SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(syclexp::nd_range_kernel<3>)
1919
void ndRangeKernelVariadic( // expected-error {{free function kernel cannot be a variadic function}}
2020
...) {}
21-
22-
// TODO: Add expected error when it will be implemented.
23-
SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(syclexp::single_task_kernel)
24-
void singleTaskKernelDefaultValues(int Value = 1) {}
25-
26-
// TODO: Add expected error when it will be implemented.
27-
SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(syclexp::nd_range_kernel<1>)
28-
void ndRangeKernelDefaultValues(int Value = 1) {}

0 commit comments

Comments
 (0)