Skip to content

Commit f86e6f8

Browse files
authored
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.
1 parent 7e780e5 commit f86e6f8

File tree

2 files changed

+64
-78
lines changed

2 files changed

+64
-78
lines changed

ctl/new.cc

Lines changed: 57 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -20,97 +20,80 @@
2020

2121
#include "libc/mem/mem.h"
2222

23-
using ctl::align_val_t;
23+
COSMOPOLITAN_C_START_
2424

25-
namespace {
26-
27-
constexpr auto a1 = align_val_t(1);
28-
29-
} // namespace
30-
31-
void*
32-
operator new(size_t n, align_val_t a)
25+
static void*
26+
_ctl_alloc(size_t n, size_t a)
3327
{
3428
void* p;
35-
if (!(p = memalign(static_cast<size_t>(a), n))) {
29+
if (!(p = memalign(a, n)))
3630
__builtin_trap();
37-
}
3831
return p;
3932
}
4033

41-
void*
42-
operator new[](size_t n, align_val_t a)
34+
static void*
35+
_ctl_alloc1(size_t n)
4336
{
44-
return operator new(n, a);
45-
}
46-
void*
47-
operator new(size_t n)
48-
{
49-
return operator new(n, a1);
50-
}
51-
void*
52-
operator new[](size_t n)
53-
{
54-
return operator new(n, a1);
37+
return _ctl_alloc(n, 1);
5538
}
5639

57-
void*
58-
operator new(size_t, void* p)
59-
{
60-
return p;
61-
}
62-
void*
63-
operator new[](size_t, void* p)
40+
static void*
41+
_ctl_ret(size_t, void* p)
6442
{
6543
return p;
6644
}
6745

68-
void
69-
operator delete(void* p) noexcept
70-
{
71-
free(p);
72-
}
73-
void
74-
operator delete[](void* p) noexcept
75-
{
76-
free(p);
77-
}
78-
void
79-
operator delete(void* p, align_val_t) noexcept
80-
{
81-
free(p);
82-
}
83-
void
84-
operator delete[](void* p, align_val_t) noexcept
85-
{
86-
free(p);
87-
}
88-
void
89-
operator delete(void* p, size_t) noexcept
90-
{
91-
free(p);
92-
}
93-
void
94-
operator delete[](void* p, size_t) noexcept
95-
{
96-
free(p);
97-
}
98-
void
99-
operator delete(void* p, size_t, align_val_t) noexcept
100-
{
101-
free(p);
102-
}
103-
void
104-
operator delete[](void* p, size_t, align_val_t) noexcept
46+
static void
47+
_ctl_free(void* p)
10548
{
10649
free(p);
10750
}
10851

109-
void
110-
operator delete(void*, void*) noexcept
111-
{
112-
}
113-
void
114-
operator delete[](void*, void*) noexcept
52+
static void
53+
_ctl_nop(void*, void*)
11554
{
11655
}
56+
57+
COSMOPOLITAN_C_END_
58+
59+
#undef __weak_reference
60+
#define __weak_reference(P, A) P __attribute__((weak, alias(#A)))
61+
62+
/* The ISO says that these should be replaceable by user code. It also says
63+
that the declarations for the first four (i.e. non placement-) operators
64+
new are implicitly available in each translation unit, including the std
65+
align_val_t parameter. (?) However, <new> also _defines_ the align_val_t
66+
type so you can’t just write your own. Our way through this morass is to
67+
supply ours as ctl::align_val_t and not implicitly declare anything, for
68+
now. If you have any brain cells left after reading this comment then go
69+
look at the eight operator delete weak references to free in the below. */
70+
71+
__weak_reference(void* operator new(size_t, ctl::align_val_t), _ctl_alloc);
72+
__weak_reference(void* operator new[](size_t, ctl::align_val_t), _ctl_alloc);
73+
__weak_reference(void* operator new(size_t), _ctl_alloc1);
74+
__weak_reference(void* operator new[](size_t), _ctl_alloc1);
75+
76+
// XXX clang-format currently mutilates these for some reason.
77+
// clang-format off
78+
79+
__weak_reference(void* operator new(size_t, void*), _ctl_ret);
80+
__weak_reference(void* operator new[](size_t, void*), _ctl_ret);
81+
82+
__weak_reference(void operator delete(void*) noexcept, _ctl_free);
83+
__weak_reference(void operator delete[](void*) noexcept, _ctl_free);
84+
#pragma GCC diagnostic push
85+
#pragma GCC diagnostic ignored "-Wattribute-alias="
86+
__weak_reference(void operator delete(void*, ctl::align_val_t) noexcept,
87+
_ctl_free);
88+
__weak_reference(void operator delete[](void*, ctl::align_val_t) noexcept,
89+
_ctl_free);
90+
__weak_reference(void operator delete(void*, size_t) noexcept, _ctl_free);
91+
__weak_reference(void operator delete[](void*, size_t) noexcept, _ctl_free);
92+
__weak_reference(void operator delete(void*, size_t, ctl::align_val_t) noexcept,
93+
_ctl_free);
94+
__weak_reference(void operator delete[](void*, size_t, ctl::align_val_t)
95+
noexcept, _ctl_free);
96+
#pragma GCC diagnostic pop
97+
98+
__weak_reference(void operator delete(void*, void*) noexcept, _ctl_nop);
99+
__weak_reference(void operator delete[](void*, void*) noexcept, _ctl_nop);

ctl/new.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,22 @@
33
#ifndef COSMOPOLITAN_CTL_NEW_H_
44
#define COSMOPOLITAN_CTL_NEW_H_
55

6-
// XXX clang-format currently mutilates these for some reason.
7-
// clang-format off
8-
96
namespace ctl {
107

11-
enum class align_val_t : size_t {};
8+
enum class align_val_t : size_t
9+
{
10+
};
1211

1312
} // namespace ctl
1413

1514
void* operator new(size_t);
1615
void* operator new[](size_t);
1716
void* operator new(size_t, ctl::align_val_t);
1817
void* operator new[](size_t, ctl::align_val_t);
18+
19+
// XXX clang-format currently mutilates these for some reason.
20+
// clang-format off
21+
1922
void* operator new(size_t, void*);
2023
void* operator new[](size_t, void*);
2124

0 commit comments

Comments
 (0)