From f86e6f8eb0fd13025c61b2e1b583628721878103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Dee=20=28J=C5=8Dshin=29?= Date: Thu, 20 Jun 2024 12:20:54 -0700 Subject: [PATCH] Make new.cc definitions weak (#1233) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The STL says that these should be replaceable by user code. new.cc now defines only a few direct functions (including a free wrapper that perplexingly is needed since g++ didn’t want to alias "free".) Now, all of the operators are weak references to those functions. --- ctl/new.cc | 131 +++++++++++++++++++++++------------------------------ ctl/new.h | 11 +++-- 2 files changed, 64 insertions(+), 78 deletions(-) diff --git a/ctl/new.cc b/ctl/new.cc index 7cac144ec..5df2d54ff 100644 --- a/ctl/new.cc +++ b/ctl/new.cc @@ -20,97 +20,80 @@ #include "libc/mem/mem.h" -using ctl::align_val_t; +COSMOPOLITAN_C_START_ -namespace { - -constexpr auto a1 = align_val_t(1); - -} // namespace - -void* -operator new(size_t n, align_val_t a) +static void* +_ctl_alloc(size_t n, size_t a) { void* p; - if (!(p = memalign(static_cast(a), n))) { + if (!(p = memalign(a, n))) __builtin_trap(); - } return p; } -void* -operator new[](size_t n, align_val_t a) +static void* +_ctl_alloc1(size_t n) { - return operator new(n, a); -} -void* -operator new(size_t n) -{ - return operator new(n, a1); -} -void* -operator new[](size_t n) -{ - return operator new(n, a1); + return _ctl_alloc(n, 1); } -void* -operator new(size_t, void* p) -{ - return p; -} -void* -operator new[](size_t, void* p) +static void* +_ctl_ret(size_t, void* p) { return p; } -void -operator delete(void* p) noexcept -{ - free(p); -} -void -operator delete[](void* p) noexcept -{ - free(p); -} -void -operator delete(void* p, align_val_t) noexcept -{ - free(p); -} -void -operator delete[](void* p, align_val_t) noexcept -{ - free(p); -} -void -operator delete(void* p, size_t) noexcept -{ - free(p); -} -void -operator delete[](void* p, size_t) noexcept -{ - free(p); -} -void -operator delete(void* p, size_t, align_val_t) noexcept -{ - free(p); -} -void -operator delete[](void* p, size_t, align_val_t) noexcept +static void +_ctl_free(void* p) { free(p); } -void -operator delete(void*, void*) noexcept -{ -} -void -operator delete[](void*, void*) noexcept +static void +_ctl_nop(void*, void*) { } + +COSMOPOLITAN_C_END_ + +#undef __weak_reference +#define __weak_reference(P, A) P __attribute__((weak, alias(#A))) + +/* The ISO says that these should be replaceable by user code. It also says + that the declarations for the first four (i.e. non placement-) operators + new are implicitly available in each translation unit, including the std + align_val_t parameter. (?) However, also _defines_ the align_val_t + type so you can’t just write your own. Our way through this morass is to + supply ours as ctl::align_val_t and not implicitly declare anything, for + now. If you have any brain cells left after reading this comment then go + look at the eight operator delete weak references to free in the below. */ + +__weak_reference(void* operator new(size_t, ctl::align_val_t), _ctl_alloc); +__weak_reference(void* operator new[](size_t, ctl::align_val_t), _ctl_alloc); +__weak_reference(void* operator new(size_t), _ctl_alloc1); +__weak_reference(void* operator new[](size_t), _ctl_alloc1); + +// XXX clang-format currently mutilates these for some reason. +// clang-format off + +__weak_reference(void* operator new(size_t, void*), _ctl_ret); +__weak_reference(void* operator new[](size_t, void*), _ctl_ret); + +__weak_reference(void operator delete(void*) noexcept, _ctl_free); +__weak_reference(void operator delete[](void*) noexcept, _ctl_free); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wattribute-alias=" +__weak_reference(void operator delete(void*, ctl::align_val_t) noexcept, + _ctl_free); +__weak_reference(void operator delete[](void*, ctl::align_val_t) noexcept, + _ctl_free); +__weak_reference(void operator delete(void*, size_t) noexcept, _ctl_free); +__weak_reference(void operator delete[](void*, size_t) noexcept, _ctl_free); +__weak_reference(void operator delete(void*, size_t, ctl::align_val_t) noexcept, + _ctl_free); +__weak_reference(void operator delete[](void*, size_t, ctl::align_val_t) + noexcept, _ctl_free); +#pragma GCC diagnostic pop + +__weak_reference(void operator delete(void*, void*) noexcept, _ctl_nop); +__weak_reference(void operator delete[](void*, void*) noexcept, _ctl_nop); diff --git a/ctl/new.h b/ctl/new.h index f227270ef..97fe85ef8 100644 --- a/ctl/new.h +++ b/ctl/new.h @@ -3,12 +3,11 @@ #ifndef COSMOPOLITAN_CTL_NEW_H_ #define COSMOPOLITAN_CTL_NEW_H_ -// XXX clang-format currently mutilates these for some reason. -// clang-format off - namespace ctl { -enum class align_val_t : size_t {}; +enum class align_val_t : size_t +{ +}; } // namespace ctl @@ -16,6 +15,10 @@ void* operator new(size_t); void* operator new[](size_t); void* operator new(size_t, ctl::align_val_t); void* operator new[](size_t, ctl::align_val_t); + +// XXX clang-format currently mutilates these for some reason. +// clang-format off + void* operator new(size_t, void*); void* operator new[](size_t, void*);