[libcxx-commits] [libcxxabi] f0054a4 - [libc++] Replace uses of _LIBCPP_WEAK with [[gnu::weak]] (#171798)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jan 13 02:21:56 PST 2026


Author: Nikolas Klauser
Date: 2026-01-13T11:21:52+01:00
New Revision: f0054a48966e684df26e589f2fc803932e03aba4

URL: https://github.com/llvm/llvm-project/commit/f0054a48966e684df26e589f2fc803932e03aba4
DIFF: https://github.com/llvm/llvm-project/commit/f0054a48966e684df26e589f2fc803932e03aba4.diff

LOG: [libc++] Replace uses of _LIBCPP_WEAK with [[gnu::weak]] (#171798)

Using `_LIBCPP_WEAK` doesn't give us anything that using `[[gnu::weak]]`
directly couldn't, so we can just expand the macro.
As a drive-by this also refactors `_LIBCPP_OVERRIDABLE_FUNCTION`.

Added: 
    

Modified: 
    libcxx/.clang-format
    libcxx/include/__config
    libcxx/src/experimental/tzdb.cpp
    libcxx/src/include/overridable_function.h
    libcxx/src/new.cpp
    libcxx/src/verbose_abort.cpp
    libcxxabi/src/stdlib_new_delete.cpp

Removed: 
    


################################################################################
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 247bd5881f516..83dc28a89bac3 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -610,10 +610,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 3dc92fb7b7f2d..fd976ba4bd799 100644
--- a/libcxx/src/experimental/tzdb.cpp
+++ b/libcxx/src/experimental/tzdb.cpp
@@ -53,7 +53,7 @@ _LIBCPP_DIAGNOSTIC_PUSH
 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-prototypes")
 // 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 288f3efa9c979..c8d9f30c74c3e 100644
--- a/libcxx/src/include/overridable_function.h
+++ b/libcxx/src/include/overridable_function.h
@@ -66,8 +66,7 @@
 #if defined(_LIBCPP_OBJECT_FORMAT_MACHO)
 
 #  define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
-#  define OVERRIDABLE_FUNCTION                                                                                         \
-    __attribute__((__section__("__TEXT,__lcxx_override,regular,pure_instructions"))) _LIBCPP_WEAK
+#  define OVERRIDABLE_FUNCTION [[gnu::weak, gnu::section("__TEXT,__lcxx_override,regular,pure_instructions")]]
 
 _LIBCPP_BEGIN_NAMESPACE_STD template <typename T, T* _Func>
 _LIBCPP_HIDE_FROM_ABI inline bool __is_function_overridden() noexcept {
@@ -99,7 +98,7 @@ _LIBCPP_END_NAMESPACE_STD
 #elif defined(_LIBCPP_OBJECT_FORMAT_ELF) && !defined(__NVPTX__)
 
 #  define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1
-#  define OVERRIDABLE_FUNCTION __attribute__((__section__("__lcxx_override"))) _LIBCPP_WEAK
+#  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.
@@ -127,7 +126,7 @@ _LIBCPP_END_NAMESPACE_STD
 #else
 
 #  define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 0
-#  define OVERRIDABLE_FUNCTION _LIBCPP_WEAK
+#  define OVERRIDABLE_FUNCTION [[gnu::weak]]
 
 #endif
 

diff  --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp
index 505d239930d81..25bdaea32f57a 100644
--- a/libcxx/src/new.cpp
+++ b/libcxx/src/new.cpp
@@ -50,7 +50,7 @@ OVERRIDABLE_FUNCTION void* operator new(std::size_t size) _THROW_BAD_ALLOC {
   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(
@@ -76,7 +76,7 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
 
 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
 
@@ -141,7 +141,7 @@ OVERRIDABLE_FUNCTION void* operator new(std::size_t size, std::align_val_t align
   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(
@@ -169,7 +169,7 @@ OVERRIDABLE_FUNCTION void* operator new[](size_t size, std::align_val_t alignmen
   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 783357c4351be..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
@@ -70,7 +66,7 @@ OVERRIDABLE_FUNCTION void* operator new(std::size_t size) _THROW_BAD_ALLOC {
   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(
@@ -96,7 +92,7 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
 
 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
 
@@ -161,7 +157,7 @@ OVERRIDABLE_FUNCTION void* operator new(std::size_t size, std::align_val_t align
   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(
@@ -189,7 +185,7 @@ OVERRIDABLE_FUNCTION void* operator new[](size_t size, std::align_val_t alignmen
   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