Skip to content

Commit 327c64c

Browse files
authored
[HIP][SPIRV] Implicit new/delete should be cdecl on host (#152023)
Client apps can (and in the case of the MSVC STL do) set cdecl explicitly on `new` / `delete` implementations. On the other hand, Clang generates implicit decls with the target's default CC. This is problematic for SPIR-V, since the default there is spir_function, which is not compatible. Since we cannot change pre-existing headers / implementations, this patch sets the CC to C for the implicit host-side decls, when compiling for device, to prevent the conflict. This is fine because the host-side overloards do not get emitted on device.
1 parent ca00689 commit 327c64c

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3497,6 +3497,19 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
34973497
}
34983498

34993499
auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) {
3500+
// The MSVC STL has explicit cdecl on its (host-side) allocation function
3501+
// specializations for the allocation, so in order to prevent a CC clash
3502+
// we use the host's CC, if available, or CC_C as a fallback, for the
3503+
// host-side implicit decls, knowing these do not get emitted when compiling
3504+
// for device.
3505+
if (getLangOpts().CUDAIsDevice && ExtraAttr &&
3506+
isa<CUDAHostAttr>(ExtraAttr) &&
3507+
Context.getTargetInfo().getTriple().isSPIRV()) {
3508+
if (auto *ATI = Context.getAuxTargetInfo())
3509+
EPI.ExtInfo = EPI.ExtInfo.withCallingConv(ATI->getDefaultCallingConv());
3510+
else
3511+
EPI.ExtInfo = EPI.ExtInfo.withCallingConv(CallingConv::CC_C);
3512+
}
35003513
QualType FnType = Context.getFunctionType(Return, Params, EPI);
35013514
FunctionDecl *Alloc = FunctionDecl::Create(
35023515
Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, FnType,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv32 -verify
2+
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64 -verify
3+
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64-amd-amdhsa -verify
4+
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv32 -aux-triple x86_64-unknown-linux-gnu -verify
5+
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64 -aux-triple x86_64-unknown-linux-gnu -verify
6+
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64-amd-amdhsa -aux-triple x86_64-unknown-linux-gnu -verify
7+
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv32 -aux-triple x86_64-pc-windows-msvc -verify
8+
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64 -aux-triple x86_64-pc-windows-msvc -verify
9+
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64-amd-amdhsa -aux-triple x86_64-pc-windows-msvc -verify
10+
11+
// expected-no-diagnostics
12+
13+
namespace std
14+
{
15+
enum class align_val_t : __SIZE_TYPE__ {};
16+
struct nothrow_t { explicit nothrow_t() = default; };
17+
extern nothrow_t const nothrow;
18+
}
19+
20+
void* __attribute__((cdecl)) operator new(__SIZE_TYPE__);
21+
void* __attribute__((cdecl)) operator new[](__SIZE_TYPE__);
22+
void* __attribute__((cdecl)) operator new(__SIZE_TYPE__, ::std::align_val_t);
23+
void* __attribute__((cdecl)) operator new[](__SIZE_TYPE__, ::std::align_val_t);
24+
25+
void __attribute__((cdecl)) operator delete(void*) noexcept;
26+
void __attribute__((cdecl)) operator delete[](void*) noexcept;
27+
void __attribute__((cdecl)) operator delete(void*, __SIZE_TYPE__) noexcept;
28+
void __attribute__((cdecl)) operator delete[](void*, __SIZE_TYPE__) noexcept;
29+
void __attribute__((cdecl)) operator delete(void*, ::std::align_val_t) noexcept;
30+
void __attribute__((cdecl)) operator delete[](void*, ::std::align_val_t) noexcept;
31+
void __attribute__((cdecl)) operator delete(void*, __SIZE_TYPE__, ::std::align_val_t) noexcept;
32+
void __attribute__((cdecl)) operator delete[](void*, __SIZE_TYPE__, ::std::align_val_t) noexcept;

0 commit comments

Comments
 (0)