https://github.com/Fznamznon created 
https://github.com/llvm/llvm-project/pull/200195

MSVC headers rely heavily on __cdecl calling convention attribute. SYCL device 
mosly uses SPIR-based targets which use spir_function default calling 
convention not compatible with __cdecl. I've made an attempt to avoid errors 
coming from MSVC headers using CUDA-style approach in 
94ca49099ef77751a33e4babe41b2ae03ff228e1 which however failed for several 
reasons. Most this happens because SYCL is implicit about what is compiled for 
device and it allows to include standard C++ headers during device 
compilations, so the approach that was taken in 
94ca49099ef77751a33e4babe41b2ae03ff228e1
didn't work for the two more cases in MSVC headers:
1. allocation/deallocation functions are marked with __cdecl and that was 
conflicting with implicit declarations of these with default calling convention.
2. due to 94ca49099ef77751a33e4babe41b2ae03ff228e1 applied, __cdecl calling 
covention attribute was preserved on functions even though it is not supported 
for the target and it declares different calling convention than the default 
that caused function types for functions with and without __cdecl attribute to 
be different and cause fail to compile MSVC headers.

>From 414f0ea0f44bc075c4a1bc4024308bf211c8da60 Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <[email protected]>
Date: Thu, 28 May 2026 07:35:44 -0700
Subject: [PATCH] [clang][SYCL] Fix compilation of MSVC headers

MSVC headers rely heavily on __cdecl calling convention attribute. SYCL
device mosly uses SPIR-based targets which use spir_function default
calling convention not compatible with __cdecl. I've made an attempt to
avoid errors coming from MSVC headers using CUDA-style approach in
94ca49099ef77751a33e4babe41b2ae03ff228e1 which however failed for
several reasons. Most this happens because SYCL is implicit about what
is compiled for device and it allows to include standard C++ headers during
device compilations, so the approach that was taken in
94ca49099ef77751a33e4babe41b2ae03ff228e1
didn't work for the two more cases in MSVC headers:
1. allocation/deallocation functions are marked with __cdecl and that
   was conflicting with implicit declarations of these with default
   calling convention.
2. due to 94ca49099ef77751a33e4babe41b2ae03ff228e1 applied, __cdecl
   calling covention attribute was preserved on functions even though it
   is not supported for the target and it declares different calling
   convention than the default that caused function types for functions
   with and without __cdecl attribute to be different and cause fail to
   compile MSVC headers.
---
 clang/lib/Sema/SemaDeclAttr.cpp    |  4 ++--
 clang/lib/Sema/SemaType.cpp        |  2 +-
 clang/test/SemaSYCL/sycl-cconv.cpp | 18 ++++++++++++++----
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index ae04d3855f01c..2b47459ac4368 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5743,10 +5743,11 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr 
&Attrs, CallingConv &CC,
   bool IsTargetDefaultMSABI =
       Context.getTargetInfo().getTriple().isOSWindows() ||
       Context.getTargetInfo().getTriple().isUEFI();
+  const TargetInfo &TI = Context.getTargetInfo();
   // TODO: diagnose uses of these conventions on the wrong target.
   switch (Attrs.getKind()) {
   case ParsedAttr::AT_CDecl:
-    CC = CC_C;
+    CC = LangOpts.SYCLIsDevice ? TI.getDefaultCallingConv() : CC_C;
     break;
   case ParsedAttr::AT_FastCall:
     CC = CC_X86FastCall;
@@ -5853,7 +5854,6 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, 
CallingConv &CC,
   }
 
   TargetInfo::CallingConvCheckResult A = TargetInfo::CCCR_OK;
-  const TargetInfo &TI = Context.getTargetInfo();
   auto *Aux = Context.getAuxTargetInfo();
   // CUDA functions may have host and/or device attributes which indicate
   // their targeted execution environment, therefore the calling convention
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 44ac4f6630690..298e076ea374c 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8380,7 +8380,7 @@ static bool handleFunctionTypeAttr(TypeProcessingState 
&state, ParsedAttr &attr,
   // much ability to diagnose it later.
   if (!supportsVariadicCall(CC)) {
     const FunctionProtoType *FnP = dyn_cast<FunctionProtoType>(fn);
-    if (FnP && FnP->isVariadic()) {
+    if (FnP && FnP->isVariadic() && !S.getLangOpts().SYCLIsDevice) {
       // stdcall and fastcall are ignored with a warning for GCC and MS
       // compatibility.
       if (CC == CC_X86StdCall || CC == CC_X86FastCall)
diff --git a/clang/test/SemaSYCL/sycl-cconv.cpp 
b/clang/test/SemaSYCL/sycl-cconv.cpp
index 664a4dbf37c49..c018e734253fe 100644
--- a/clang/test/SemaSYCL/sycl-cconv.cpp
+++ b/clang/test/SemaSYCL/sycl-cconv.cpp
@@ -4,14 +4,11 @@
 // Check that there is no error/warning emitted for cdecl functions compiled 
for
 // SYCL device. Make sure variadic calls from within device code are diagnosed.
 
-// no-aux-warning@+2 {{'__cdecl' calling convention is not supported for this 
target}}
-// 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.
 [[clang::sycl_external]] int foo(int, ...) { return 0; }
 
-// no-aux-warning@+1 {{'__cdecl' calling convention is not supported for this 
target}}
 __inline __cdecl int moo() { return 0; }
 
 void bar() {
@@ -27,11 +24,24 @@ void sycl_kernel_launch(Args ...args) {}
 
 template<typename KN, typename K>
 [[clang::sycl_kernel_entry_point(KN)]]
-// no-aux-warning@+1 {{'__cdecl' calling convention is not supported for this 
target}}
 __cdecl void sycl_entry_point(K k) {
   k(); // expected-note {{called by}}
 }
 
+// No errors for deallocation/allocation functions.
+void __cdecl operator delete(void *) noexcept;
+
+// Make sure that function type conversions work.
+typedef void (__cdecl *funcTy)();
+void invoke(funcTy f);
+
+static void callee() noexcept {
+}
+
+void foo() {
+   invoke(callee);
+}
+
 int main() {
   //expected-error@+1 {{SYCL device code does not support variadic functions}}
   sycl_entry_point<class kn>([]() { printf("world\n");

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

Reply via email to