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
