[clang] [clang][SYCL] Diagnose variadic sycl_external function (PR #216393)

via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 14 13:26:50 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-spir-v

Author: schittir

<details>
<summary>Changes</summary>

SYCL device code does not support variadic functions.

---
Full diff: https://github.com/llvm/llvm-project/pull/216393.diff


5 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2) 
- (modified) clang/lib/Sema/SemaSYCL.cpp (+5) 
- (modified) clang/test/CodeGenSPIRV/spirv-host-adaptation-valist.cpp (+5-4) 
- (modified) clang/test/SemaSYCL/sycl-cconv.cpp (+1-1) 
- (modified) clang/test/SemaSYCL/sycl-external-attr.cpp (+16) 


``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b314c17ad27bd..3816eafaf7e3c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13545,6 +13545,8 @@ def err_sycl_external_invalid_main : Error<
   "%0 cannot be applied to the 'main' function">;
 def err_sycl_external_invalid_deleted_function : Error<
   "%0 cannot be applied to an explicitly deleted function">;
+def err_sycl_external_invalid_variadic_function : Error<
+  "%0 cannot be applied to a variadic function">;
 def warn_sycl_external_missing_on_first_decl : Warning<
   "%0 attribute does not appear on the first declaration">,
   InGroup<NonPortableSYCL>;
diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp
index b942f19761f40..0f2f5753d4136 100644
--- a/clang/lib/Sema/SemaSYCL.cpp
+++ b/clang/lib/Sema/SemaSYCL.cpp
@@ -293,6 +293,11 @@ void SemaSYCL::CheckSYCLExternalFunctionDecl(FunctionDecl *FD) {
          diag::err_sycl_external_invalid_deleted_function)
         << SEAttr;
   }
+  if (FD->isVariadic()) {
+    Diag(SEAttr->getLocation(),
+         diag::err_sycl_external_invalid_variadic_function)
+        << SEAttr;
+  }
 }
 
 void SemaSYCL::CheckSYCLEntryPointFunctionDecl(FunctionDecl *FD) {
diff --git a/clang/test/CodeGenSPIRV/spirv-host-adaptation-valist.cpp b/clang/test/CodeGenSPIRV/spirv-host-adaptation-valist.cpp
index d926e30376b18..799eaf257af71 100644
--- a/clang/test/CodeGenSPIRV/spirv-host-adaptation-valist.cpp
+++ b/clang/test/CodeGenSPIRV/spirv-host-adaptation-valist.cpp
@@ -5,9 +5,10 @@
 // RUN: %clang_cc1 -triple spirv64-unknown-unknown -aux-triple x86_64-pc-windows-msvc \
 // RUN:   -fsycl-is-device -emit-llvm -o - %s | FileCheck --check-prefix=WINDOWS %s
 
-[[clang::sycl_external]] int f(int n, ...) {
+/// No variadic functions in SYCL device code, so 'ap' comes from the caller.
+[[clang::sycl_external]] int f(__builtin_va_list *ap) {
   __builtin_va_list ap1, ap2;
-  __builtin_va_start(ap1, n);
+  __builtin_va_copy(ap1, *ap);
   int v = __builtin_va_arg(ap1, int);
   __builtin_va_copy(ap2, ap1);
   __builtin_va_end(ap1);
@@ -15,10 +16,10 @@
   return v;
 }
 
-// LINUX:    define {{.*}} i32 @_Z1fiz(i32 noundef %n, ...) {{.*}} {
+// LINUX:    define {{.*}} i32 @_Z1fPA1_13__va_list_tag(
 // LINUX:      %ap1 = alloca [1 x %struct.__va_list_tag], align 8
 // LINUX:      %ap2 = alloca [1 x %struct.__va_list_tag], align 8
 
-// WINDOWS:  define {{.*}} i32 @_Z1fiz(i32 noundef %n, ...) {{.*}} {
+// WINDOWS:  define {{.*}} i32 @_Z1fPPc(
 // WINDOWS:    %ap1 = alloca ptr addrspace(4), align 8
 // WINDOWS:    %ap2 = alloca ptr addrspace(4), align 8
diff --git a/clang/test/SemaSYCL/sycl-cconv.cpp b/clang/test/SemaSYCL/sycl-cconv.cpp
index 664a4dbf37c49..1d3ba97b624bf 100644
--- a/clang/test/SemaSYCL/sycl-cconv.cpp
+++ b/clang/test/SemaSYCL/sycl-cconv.cpp
@@ -8,7 +8,7 @@
 // no-aux-error at +1 {{variadic function cannot use spir_function calling convention}}
 __inline __cdecl int printf(char const* const _Format, ...) { return 0; }
 
-// FIXME: that should be diagnosed.
+// expected-error at +1 {{'clang::sycl_external' cannot be applied to a variadic function}}
 [[clang::sycl_external]] int foo(int, ...) { return 0; }
 
 // no-aux-warning at +1 {{'__cdecl' calling convention is not supported for this target}}
diff --git a/clang/test/SemaSYCL/sycl-external-attr.cpp b/clang/test/SemaSYCL/sycl-external-attr.cpp
index ebda94e7d5030..22f4276d5a547 100644
--- a/clang/test/SemaSYCL/sycl-external-attr.cpp
+++ b/clang/test/SemaSYCL/sycl-external-attr.cpp
@@ -113,6 +113,22 @@ class D {
 // expected-error at +1{{'clang::sycl_external' cannot be applied to an explicitly deleted function}}
 [[clang::sycl_external]] void del() = delete;
 
+// SYCL device code does not support variadic functions.
+// expected-error at +1{{'clang::sycl_external' cannot be applied to a variadic function}}
+[[clang::sycl_external]] void var(int, ...) {}
+
+// expected-error at +1{{'clang::sycl_external' cannot be applied to a variadic function}}
+[[clang::sycl_external]] void vardecl(int, ...);
+
+// expected-error at +2{{'clang::sycl_external' cannot be applied to a variadic function}}
+class E {
+  [[clang::sycl_external]] void mvar(int, ...) {}
+};
+
+template<typename... Ts>
+[[clang::sycl_external]] void pack(Ts...) {}
+template void pack(int);
+
 struct NonCopyable {
   ~NonCopyable() = delete;
   [[clang::sycl_external]] NonCopyable(const NonCopyable&) = default;

``````````

</details>


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


More information about the cfe-commits mailing list