[libc-commits] [libc] [libc] Add and use 'cpp::launder' to guard placement new (PR #146123)
Joseph Huber via libc-commits
libc-commits at lists.llvm.org
Fri Jun 27 10:51:17 PDT 2025
https://github.com/jhuber6 created https://github.com/llvm/llvm-project/pull/146123
Summary:
In the GPU allocator we reinterpret cast from a void pointer. We know
that an actual object was constructed there according to the C++ object
model, but to make it fully standards compliant we need to 'launder' it
to forward that information to the compiler. Add this function and call
it as appropriate.
>From 27f8c072db6e7df435aa25c59693f00254ff105e Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Fri, 27 Jun 2025 12:49:20 -0500
Subject: [PATCH] [libc] Add and use 'cpp::launder' to guard placement new
Summary:
In the GPU allocator we reinterpret cast from a void pointer. We know
that an actual object was constructed there according to the C++ object
model, but to make it fully standards compliant we need to 'launder' it
to forward that information to the compiler. Add this function and call
it as appropriate.
---
libc/src/__support/CPP/new.h | 8 ++++++++
libc/src/__support/GPU/allocator.cpp | 4 ++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/libc/src/__support/CPP/new.h b/libc/src/__support/CPP/new.h
index 8694d9c475507..fe36de29468a8 100644
--- a/libc/src/__support/CPP/new.h
+++ b/libc/src/__support/CPP/new.h
@@ -29,6 +29,14 @@ enum class align_val_t : size_t {};
namespace LIBC_NAMESPACE_DECL {
+namespace cpp {
+template <class T> [[nodiscard]] constexpr T *launder(T *p) {
+ static_assert(__has_builtin(__builtin_launder),
+ "cpp::launder requires __builtin_launder");
+ return __builtin_launder(p);
+}
+} // namespace cpp
+
class AllocChecker {
bool success = false;
diff --git a/libc/src/__support/GPU/allocator.cpp b/libc/src/__support/GPU/allocator.cpp
index 66ab155e5c299..5ea27a9c44b66 100644
--- a/libc/src/__support/GPU/allocator.cpp
+++ b/libc/src/__support/GPU/allocator.cpp
@@ -544,8 +544,8 @@ void deallocate(void *ptr) {
return impl::rpc_free(ptr);
// The original slab pointer is the 2MiB boundary using the given pointer.
- Slab *slab = reinterpret_cast<Slab *>(
- (reinterpret_cast<uintptr_t>(ptr) & ~SLAB_ALIGNMENT));
+ Slab *slab = cpp::launder(reinterpret_cast<Slab *>(
+ (reinterpret_cast<uintptr_t>(ptr) & ~SLAB_ALIGNMENT)));
slab->deallocate(ptr);
release_slab(slab);
}
More information about the libc-commits
mailing list