[clang] [clang][SYCL] Diagnose reference kernel parameters (PR #192957)

Tom Honermann via cfe-commits cfe-commits at lists.llvm.org
Thu May 28 15:49:21 PDT 2026


================
@@ -0,0 +1,122 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsyntax-only -Wno-vla-cxx-extension -fsycl-is-host -verify %s
+// RUN: %clang_cc1 -triple spirv64 -std=c++17 -fsyntax-only -Wno-vla-cxx-extension -fsycl-is-device -verify %s
+
+// A unique kernel name type is required for each declared kernel entry point.
+template<int, int = 0> struct KN;
+
+// A generic kernel launch function.
+template<typename KNT, typename... Ts>
+void sycl_kernel_launch(const char *, Ts...) {}
+
+// Kernel entry point template definition.
+template<typename KNT, typename T>
+[[clang::sycl_kernel_entry_point(KNT)]]
+void kernel_single_task(T) {}
+
+// Check that reference captures of kernel that defined as lambda are diagnosed.
+namespace badref1 {
+void test() {
+  int p = 0;
+  double q = 0;
+  float s = 0;
+  kernel_single_task<class KN<1>>( // expected-note {{requested here}}
+      [ // expected-note2{{within field of type}}
+          // expected-error at +1 {{'int &' cannot be used as the type of a kernel parameter}}
+          &p, q,
+          // expected-error at +1 {{'float &' cannot be used as the type of a kernel parameter}}
+          &s] {
+        (void)q;
+        (void)p;
+        (void)s;
+      });
+}
+} // namespace badref1
+
+// Check reference kernel parameters witin structs or lambdas;
+namespace badref2 {
+struct S { // expected-note 2{{within field of type 'S' declared here}}
+  int a;
+  int &b; //expected-error 2{{'int &' cannot be used as the type of a kernel parameter}}
+};
+
+void test() {
+  int p = 0;
+  auto L = [&]() { (void)p;}; // expected-error {{'int &' cannot be used as the type of a kernel parameter}}
+                               // expected-note at -1 {{within field of type}}
+  S Str {p, p};
+  kernel_single_task<class KN<2>>( // expected-note {{requested here}}
+      [=] { // expected-note 2{{within field of type}}
+        (void)L;
+        (void)Str; // no error because fail for L already
+      });
+
+  kernel_single_task<class KN<3>>( // expected-note {{requested here}}
+     [=] { // // expected-note {{within field of type}}
+       (void)Str;
+     });
+
+}
+} // namespace badref2
+
+// Check references within array kernel parameters.
+namespace badref3 {
+struct S { // expected-note {{within field of type 'S' declared here}}
+  int a;
+  int &b; //expected-error {{'int &' cannot be used as the type of a kernel parameter}}
+};
+
+void fooarr(int (&arr)[5]) {
+}
+
+void test(int AS) {
+  int p = 0;
+  S Str {p, p};
+  S arr[2] = {Str, Str};
+  kernel_single_task<class KN<4>>( // expected-note {{requested here}}
+      [=] { // expected-note {{within field of type}}
+        (void)arr;
+      });
+  int arr1[AS];
+  kernel_single_task<class KN<5>>( // expected-note {{requested here}}
+      [&] { // expected-note {{within field of type}}
+        (void)arr1; // expected-error {{'int (&)[AS]' cannot be used as the type of a kernel parameter}}
+      });
+  int arrayints[5] = {0};
+  kernel_single_task<class KN<7>>( // expected-note {{requested here}}
+      [&] { // expected-note {{within field of type}}
+        fooarr(arrayints); // expected-error {{'int (&)[5]' cannot be used as the type of a kernel parameter}}
+      });
----------------
tahonermann wrote:

"within field" is the wrong terminology here since the notes are referencing lambda captures. Can the diagnostic be updated to differentiate these cases? E.g., "within captured variable of type ...".

https://github.com/llvm/llvm-project/pull/192957


More information about the cfe-commits mailing list