[libcxx-commits] [libcxx] [libcxxabi] [libc++] Replase uses of _LIBCPP_WEAK with [[gnu::weak]] (PR #171798)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Dec 11 05:59:05 PST 2025
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/171798
>From 2dcb613cc42376a48cc0582aa2259bf5cee76388 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 11 Dec 2025 11:48:53 +0100
Subject: [PATCH] [libc++] Replase uses of _LIBCPP_WEAK with [[gnu::weak]]
---
libcxx/.clang-format | 1 -
libcxx/include/__config | 4 ---
libcxx/src/experimental/tzdb.cpp | 2 +-
libcxx/src/include/overridable_function.h | 14 ++++----
libcxx/src/new.cpp | 40 ++++++++++-----------
libcxx/src/verbose_abort.cpp | 2 +-
libcxxabi/src/stdlib_new_delete.cpp | 44 +++++++++++------------
7 files changed, 48 insertions(+), 59 deletions(-)
diff --git a/libcxx/.clang-format b/libcxx/.clang-format
index 9557b955cd72c..38f8fdb0703f6 100644
--- a/libcxx/.clang-format
+++ b/libcxx/.clang-format
@@ -53,7 +53,6 @@ AttributeMacros: [
'_LIBCPP_TRY_ACQUIRE_CAPABILITY',
'_LIBCPP_TRY_ACQUIRE_SHARED_CAPABILITY',
'_LIBCPP_USING_IF_EXISTS',
- '_LIBCPP_WEAK',
]
BinPackArguments: false
BinPackParameters: false
diff --git a/libcxx/include/__config b/libcxx/include/__config
index e758acfa870ae..c0c7c3b5c2abe 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -620,10 +620,6 @@ typedef __char32_t char32_t;
# define _LIBCPP_CONSTEXPR_SINCE_CXX26
# endif
-# ifndef _LIBCPP_WEAK
-# define _LIBCPP_WEAK __attribute__((__weak__))
-# endif
-
// Thread API
// clang-format off
# if _LIBCPP_HAS_THREADS && \
diff --git a/libcxx/src/experimental/tzdb.cpp b/libcxx/src/experimental/tzdb.cpp
index 9e3aae32a01a4..5ffbb36ef8458 100644
--- a/libcxx/src/experimental/tzdb.cpp
+++ b/libcxx/src/experimental/tzdb.cpp
@@ -51,7 +51,7 @@ namespace chrono {
// This function is weak so it can be overriden in the tests. The
// declaration is in the test header test/support/test_tzdb.h
-_LIBCPP_WEAK string_view __libcpp_tzdb_directory() {
+[[gnu::weak]] string_view __libcpp_tzdb_directory() {
#if defined(__linux__)
return "/usr/share/zoneinfo/";
#else
diff --git a/libcxx/src/include/overridable_function.h b/libcxx/src/include/overridable_function.h
index 0b43f271486c1..0e3c79edc4347 100644
--- a/libcxx/src/include/overridable_function.h
+++ b/libcxx/src/include/overridable_function.h
@@ -29,12 +29,12 @@
// This is a low-level utility which does not work on all platforms, since it needs
// to make assumptions about the object file format in use. Furthermore, it requires
// the "base definition" of the function (the one we want to check whether it has been
-// overridden) to be defined using the _LIBCPP_OVERRIDABLE_FUNCTION macro.
+// overridden) to be defined using the OVERRIDABLE_FUNCTION macro.
//
// This currently works with Mach-O files (used on Darwin) and with ELF files (used on Linux
// and others). On platforms where we know how to implement this detection, the macro
// _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION is defined to 1, and it is defined to 0 on
-// other platforms. The _LIBCPP_OVERRIDABLE_FUNCTION macro is defined to perform a normal
+// other platforms. The OVERRIDABLE_FUNCTION macro is defined to perform a normal
// function definition on unsupported platforms so that it can be used to define functions
// regardless of whether detection is actually supported.
//
@@ -44,7 +44,7 @@
// Let's say we want to check whether a weak function `f` has been overridden by the user.
// The general mechanism works by placing `f`'s definition (in the libc++ built library)
// inside a special section, which we do using the `__section__` attribute via the
-// _LIBCPP_OVERRIDABLE_FUNCTION macro.
+// OVERRIDABLE_FUNCTION macro.
//
// Then, when comes the time to check whether the function has been overridden, we take
// the address of the function and we check whether it falls inside the special function
@@ -66,8 +66,7 @@
#if defined(_LIBCPP_OBJECT_FORMAT_MACHO)
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
-# define _LIBCPP_OVERRIDABLE_FUNCTION(type, name, arglist) \
- __attribute__((__section__("__TEXT,__lcxx_override,regular,pure_instructions"))) _LIBCPP_WEAK type name arglist
+# define OVERRIDABLE_FUNCTION [[gnu::weak, gnu::section("__TEXT,__lcxx_override,regular,pure_instructions")]]
_LIBCPP_BEGIN_NAMESPACE_STD
template <typename T, T* _Func>
@@ -100,8 +99,7 @@ _LIBCPP_END_NAMESPACE_STD
#elif defined(_LIBCPP_OBJECT_FORMAT_ELF) && !defined(__NVPTX__)
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
-# define _LIBCPP_OVERRIDABLE_FUNCTION(type, name, arglist) \
- __attribute__((__section__("__lcxx_override"))) _LIBCPP_WEAK type name arglist
+# define OVERRIDABLE_FUNCTION [[gnu::weak, gnu::section("__lcxx_override")]]
// This is very similar to what we do for Mach-O above. The ELF linker will implicitly define
// variables with those names corresponding to the start and the end of the section.
@@ -129,7 +127,7 @@ _LIBCPP_END_NAMESPACE_STD
#else
# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 0
-# define _LIBCPP_OVERRIDABLE_FUNCTION(type, name, arglist) _LIBCPP_WEAK type name arglist
+# define OVERRIDABLE_FUNCTION [[gnu::weak]]
#endif
diff --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp
index 70cdab683a861..25bdaea32f57a 100644
--- a/libcxx/src/new.cpp
+++ b/libcxx/src/new.cpp
@@ -43,14 +43,14 @@ static void* operator_new_impl(std::size_t size) {
return p;
}
-_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new, (std::size_t size)) _THROW_BAD_ALLOC {
+OVERRIDABLE_FUNCTION void* operator new(std::size_t size) _THROW_BAD_ALLOC {
void* p = operator_new_impl(size);
if (p == nullptr)
__throw_bad_alloc_shim();
return p;
}
-_LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void* operator new(size_t size, const std::nothrow_t&) noexcept {
# if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
@@ -74,9 +74,9 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
# endif
}
-_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new[], (size_t size)) _THROW_BAD_ALLOC { return ::operator new(size); }
+OVERRIDABLE_FUNCTION void* operator new[](size_t size) _THROW_BAD_ALLOC { return ::operator new(size); }
-_LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void* operator new[](size_t size, const std::nothrow_t&) noexcept {
# if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
@@ -100,17 +100,17 @@ _LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
# endif
}
-_LIBCPP_WEAK void operator delete(void* ptr) noexcept { std::free(ptr); }
+[[gnu::weak]] void operator delete(void* ptr) noexcept { std::free(ptr); }
-_LIBCPP_WEAK void operator delete(void* ptr, const std::nothrow_t&) noexcept { ::operator delete(ptr); }
+[[gnu::weak]] void operator delete(void* ptr, const std::nothrow_t&) noexcept { ::operator delete(ptr); }
-_LIBCPP_WEAK void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); }
+[[gnu::weak]] void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); }
-_LIBCPP_WEAK void operator delete[](void* ptr) noexcept { ::operator delete(ptr); }
+[[gnu::weak]] void operator delete[](void* ptr) noexcept { ::operator delete(ptr); }
-_LIBCPP_WEAK void operator delete[](void* ptr, const std::nothrow_t&) noexcept { ::operator delete[](ptr); }
+[[gnu::weak]] void operator delete[](void* ptr, const std::nothrow_t&) noexcept { ::operator delete[](ptr); }
-_LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
+[[gnu::weak]] void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
# if _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
@@ -134,14 +134,14 @@ static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignm
return p;
}
-_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new, (std::size_t size, std::align_val_t alignment)) _THROW_BAD_ALLOC {
+OVERRIDABLE_FUNCTION void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
void* p = operator_new_aligned_impl(size, alignment);
if (p == nullptr)
__throw_bad_alloc_shim();
return p;
}
-_LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
# if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
@@ -165,11 +165,11 @@ _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const s
# endif
}
-_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new[], (size_t size, std::align_val_t alignment)) _THROW_BAD_ALLOC {
+OVERRIDABLE_FUNCTION void* operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
return ::operator new(size, alignment);
}
-_LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
# if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
@@ -193,25 +193,25 @@ _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const
# endif
}
-_LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); }
+[[gnu::weak]] void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); }
-_LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
::operator delete(ptr, alignment);
}
-_LIBCPP_WEAK void operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept {
+[[gnu::weak]] void operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept {
::operator delete(ptr, alignment);
}
-_LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment) noexcept {
+[[gnu::weak]] void operator delete[](void* ptr, std::align_val_t alignment) noexcept {
::operator delete(ptr, alignment);
}
-_LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
::operator delete[](ptr, alignment);
}
-_LIBCPP_WEAK void operator delete[](void* ptr, size_t, std::align_val_t alignment) noexcept {
+[[gnu::weak]] void operator delete[](void* ptr, size_t, std::align_val_t alignment) noexcept {
::operator delete[](ptr, alignment);
}
diff --git a/libcxx/src/verbose_abort.cpp b/libcxx/src/verbose_abort.cpp
index 94bdb451dee7a..afe20c3cd0b16 100644
--- a/libcxx/src/verbose_abort.cpp
+++ b/libcxx/src/verbose_abort.cpp
@@ -23,7 +23,7 @@ extern "C" void android_set_abort_message(const char* msg);
_LIBCPP_BEGIN_NAMESPACE_STD
-_LIBCPP_WEAK void __libcpp_verbose_abort(char const* format, ...) noexcept {
+[[gnu::weak]] void __libcpp_verbose_abort(char const* format, ...) noexcept {
// Write message to stderr. We do this before formatting into a
// buffer so that we still get some information out if that fails.
{
diff --git a/libcxxabi/src/stdlib_new_delete.cpp b/libcxxabi/src/stdlib_new_delete.cpp
index dbb75b128a2a4..164a26335eb38 100644
--- a/libcxxabi/src/stdlib_new_delete.cpp
+++ b/libcxxabi/src/stdlib_new_delete.cpp
@@ -20,10 +20,6 @@
# error The _THROW_BAD_ALLOC macro should be already defined by libc++
#endif
-#ifndef _LIBCPP_WEAK
-# error The _LIBCPP_WEAK macro should be already defined by libc++
-#endif
-
#if defined(_LIBCXXABI_NO_EXCEPTIONS) != !_LIBCPP_HAS_EXCEPTIONS
# error libc++ and libc++abi seem to disagree on whether exceptions are enabled
#endif
@@ -63,14 +59,14 @@ static void* operator_new_impl(std::size_t size) {
return p;
}
-_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new, (std::size_t size)) _THROW_BAD_ALLOC {
+OVERRIDABLE_FUNCTION void* operator new(std::size_t size) _THROW_BAD_ALLOC {
void* p = operator_new_impl(size);
if (p == nullptr)
__throw_bad_alloc_shim();
return p;
}
-_LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void* operator new(size_t size, const std::nothrow_t&) noexcept {
#if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
@@ -94,9 +90,9 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
#endif
}
-_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new[], (size_t size)) _THROW_BAD_ALLOC { return ::operator new(size); }
+OVERRIDABLE_FUNCTION void* operator new[](size_t size) _THROW_BAD_ALLOC { return ::operator new(size); }
-_LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void* operator new[](size_t size, const std::nothrow_t&) noexcept {
#if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
@@ -120,17 +116,17 @@ _LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
#endif
}
-_LIBCPP_WEAK void operator delete(void* ptr) noexcept { std::free(ptr); }
+[[gnu::weak]] void operator delete(void* ptr) noexcept { std::free(ptr); }
-_LIBCPP_WEAK void operator delete(void* ptr, const std::nothrow_t&) noexcept { ::operator delete(ptr); }
+[[gnu::weak]] void operator delete(void* ptr, const std::nothrow_t&) noexcept { ::operator delete(ptr); }
-_LIBCPP_WEAK void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); }
+[[gnu::weak]] void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); }
-_LIBCPP_WEAK void operator delete[](void* ptr) noexcept { ::operator delete(ptr); }
+[[gnu::weak]] void operator delete[](void* ptr) noexcept { ::operator delete(ptr); }
-_LIBCPP_WEAK void operator delete[](void* ptr, const std::nothrow_t&) noexcept { ::operator delete[](ptr); }
+[[gnu::weak]] void operator delete[](void* ptr, const std::nothrow_t&) noexcept { ::operator delete[](ptr); }
-_LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
+[[gnu::weak]] void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
#if _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION
@@ -154,14 +150,14 @@ static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignm
return p;
}
-_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new, (std::size_t size, std::align_val_t alignment)) _THROW_BAD_ALLOC {
+OVERRIDABLE_FUNCTION void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
void* p = operator_new_aligned_impl(size, alignment);
if (p == nullptr)
__throw_bad_alloc_shim();
return p;
}
-_LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
# if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
@@ -185,11 +181,11 @@ _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const s
# endif
}
-_LIBCPP_OVERRIDABLE_FUNCTION(void*, operator new[], (size_t size, std::align_val_t alignment)) _THROW_BAD_ALLOC {
+OVERRIDABLE_FUNCTION void* operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
return ::operator new(size, alignment);
}
-_LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
# if !_LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
_LIBCPP_ASSERT_SHIM(
@@ -213,25 +209,25 @@ _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const
# endif
}
-_LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); }
+[[gnu::weak]] void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); }
-_LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
::operator delete(ptr, alignment);
}
-_LIBCPP_WEAK void operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept {
+[[gnu::weak]] void operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept {
::operator delete(ptr, alignment);
}
-_LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment) noexcept {
+[[gnu::weak]] void operator delete[](void* ptr, std::align_val_t alignment) noexcept {
::operator delete(ptr, alignment);
}
-_LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
+[[gnu::weak]] void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
::operator delete[](ptr, alignment);
}
-_LIBCPP_WEAK void operator delete[](void* ptr, size_t, std::align_val_t alignment) noexcept {
+[[gnu::weak]] void operator delete[](void* ptr, size_t, std::align_val_t alignment) noexcept {
::operator delete[](ptr, alignment);
}
More information about the libcxx-commits
mailing list