[libc++] Simplify std::launder (#147985)

Both Clang and GCC diagnose invalid calls to `__builtin_launder`, which
causes duplicate diagnostics when using `std::launder` in an invalid
way. While the diagnostic message for the builtin isn't perferct, it's
definitely good enough to understand the problem and adding our own
diagnostic doesn't really make things any clearer. Because of that, this
patch simply removes the `static_assert`s and lets the compiler handle
diagnosing incorrect arguments instead. This not only simplifies our
implementation, but also improves compile times a bit, since we avoid
instantiating some type traits.
This commit is contained in:
Nikolas Klauser
2025-07-16 09:42:09 +02:00
committed by GitHub
parent f223411e2e
commit db2eb4d031
2 changed files with 7 additions and 10 deletions

View File

@@ -10,8 +10,6 @@
#define _LIBCPP___NEW_LAUNDER_H
#include <__config>
#include <__type_traits/is_function.h>
#include <__type_traits/is_void.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -20,15 +18,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT {
static_assert(!(is_function<_Tp>::value), "can't launder functions");
static_assert(!is_void<_Tp>::value, "can't launder cv-void");
// The compiler diagnoses misuses of __builtin_launder, so we don't need to add any static_asserts
// to implement the Mandates.
return __builtin_launder(__p);
}
#if _LIBCPP_STD_VER >= 17
template <class _Tp>
[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp* launder(_Tp* __p) noexcept {
return std::__launder(__p);
return __builtin_launder(__p);
}
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@@ -25,12 +25,11 @@ int main(int, char**) {
(void)std::launder((void*)nullptr);
(void)std::launder((const void*)nullptr);
(void)std::launder((volatile void*)nullptr);
(void)std::launder(
(const volatile void*)nullptr); // expected-error-re@*:* 4 {{static assertion failed{{.*}}can't launder cv-void}}
// expected-error@*:* 0-4 {{void pointer argument to '__builtin_launder' is not allowed}}
(void)std::launder((const volatile void*)nullptr);
// expected-error@*:* 4 {{void pointer argument to '__builtin_launder' is not allowed}}
(void)std::launder(foo); // expected-error-re@*:* 1 {{static assertion failed{{.*}}can't launder functions}}
// expected-error@*:* 0-1 {{function pointer argument to '__builtin_launder' is not allowed}}
(void)std::launder(foo);
// expected-error@*:* 1 {{function pointer argument to '__builtin_launder' is not allowed}}
return 0;
}