Make new.cc definitions weak (#1233)

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.
This commit is contained in:
Steven Dee (Jōshin) 2024-06-20 12:20:54 -07:00 committed by GitHub
parent 7e780e57d4
commit f86e6f8eb0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 64 additions and 78 deletions

View file

@ -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<size_t>(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, <new> also _defines_ the align_val_t
type so you cant 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);

View file

@ -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*);