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

SYCL device code does not support variadic functions.

>From 0feaeafbb0cdc1e36195c1dd40804969dada3d83 Mon Sep 17 00:00:00 2001
From: Sindhu Chittireddy <[email protected]>
Date: Fri, 14 Aug 2026 11:10:01 -0700
Subject: [PATCH] [clang][SYCL] Diagnose variadic sycl_external functions at
 their declaration

SYCL device code does not support variadic functions.
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  2 ++
 clang/lib/Sema/SemaSYCL.cpp                      |  5 +++++
 .../spirv-host-adaptation-valist.cpp             |  9 +++++----
 clang/test/SemaSYCL/sycl-cconv.cpp               |  2 +-
 clang/test/SemaSYCL/sycl-external-attr.cpp       | 16 ++++++++++++++++
 5 files changed, 29 insertions(+), 5 deletions(-)

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@+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@+1 {{'clang::sycl_external' cannot be applied to a variadic 
function}}
 [[clang::sycl_external]] int foo(int, ...) { return 0; }
 
 // no-aux-warning@+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@+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@+1{{'clang::sycl_external' cannot be applied to a variadic 
function}}
+[[clang::sycl_external]] void var(int, ...) {}
+
+// expected-error@+1{{'clang::sycl_external' cannot be applied to a variadic 
function}}
+[[clang::sycl_external]] void vardecl(int, ...);
+
+// expected-error@+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;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to