-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Expand file tree
/
Copy pathallocators.cpp
More file actions
184 lines (150 loc) · 5.23 KB
/
allocators.cpp
File metadata and controls
184 lines (150 loc) · 5.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// semmle-extractor-options: -std=c++20
typedef unsigned long size_t;
namespace std {
enum class align_val_t : size_t {};
struct destroying_delete_t {
explicit destroying_delete_t() = default;
};
inline constexpr destroying_delete_t destroying_delete{};
}
void* operator new(size_t, float);
void* operator new[](size_t, float);
void* operator new(size_t, std::align_val_t, float);
void* operator new[](size_t, std::align_val_t, float);
void operator delete(void*, float);
void operator delete[](void*, float);
void operator delete(void*, std::align_val_t, float);
void operator delete[](void*, std::align_val_t, float);
struct String {
String();
String(const String&);
String(String&&);
String(const char*);
~String();
String& operator=(const String&);
String& operator=(String&&);
const char* c_str() const;
private:
const char* p;
};
struct SizedDealloc {
char a[32];
void* operator new(size_t);
void* operator new[](size_t);
void operator delete(void*, size_t);
void operator delete[](void*, size_t);
};
struct DestroyingDealloc {
void* operator new(size_t);
void operator delete(DestroyingDealloc*, std::destroying_delete_t);
};
struct alignas(128) Overaligned {
char a[256];
};
struct PolymorphicBase {
virtual ~PolymorphicBase();
};
void OperatorNew() {
new int; // No constructor
new(1.0f) int; // Placement new, no constructor
new int(); // Zero-init
new String(); // Constructor
new(1.0f) String("hello"); // Placement new, constructor with args
new Overaligned; // Aligned new
new(1.0f) Overaligned(); // Placement aligned new
}
void OperatorDelete() {
delete static_cast<int*>(nullptr); // No destructor
delete static_cast<String*>(nullptr); // Non-virtual destructor, with size.
delete static_cast<SizedDealloc*>(nullptr); // No destructor, with size.
delete static_cast<DestroyingDealloc*>(nullptr); // No destructor, with destroying delete.
delete static_cast<Overaligned*>(nullptr); // No destructor, with size and alignment.
delete static_cast<PolymorphicBase*>(nullptr); // Virtual destructor
delete static_cast<const String*>(nullptr); // Pointer to const
}
void OperatorNewArray(int n) {
new int[n]; // No constructor
new(1.0f) int[n]; // Placement new, no constructor
new String[n]; // Constructor
new Overaligned[n]; // Aligned new
new String[10]; // Constant size
}
int* const GetPointer();
void OperatorDeleteArray() {
delete[] static_cast<int*>(nullptr); // No destructor
delete[] static_cast<String*>(nullptr); // Non-virtual destructor, with size.
delete[] static_cast<SizedDealloc*>(nullptr); // No destructor, with size.
delete[] static_cast<Overaligned*>(nullptr); // No destructor, with size and alignment.
delete[] static_cast<PolymorphicBase*>(nullptr); // Virtual destructor
delete[] GetPointer();
}
struct FailedInit {
FailedInit();
~FailedInit();
void* operator new(size_t); // Non-placement
void* operator new[](size_t); // Non-placement
void operator delete(void*, size_t); // Sized deallocation
void operator delete[](void*, size_t); // Sized deallocation
};
struct alignas(128) FailedInitOveraligned {
FailedInitOveraligned();
~FailedInitOveraligned();
void* operator new(size_t, std::align_val_t, float); // Aligned placement
void* operator new[](size_t, std::align_val_t, float); // Aligned placement
void operator delete(void*, std::align_val_t, float); // Aligned placement
void operator delete[](void*, std::align_val_t, float); // Aligned placement
};
struct alignas(128) FailedInitDestroyingDelete {
FailedInitDestroyingDelete();
~FailedInitDestroyingDelete();
void* operator new(size_t); // Non-placement
void operator delete(FailedInitDestroyingDelete*, std::destroying_delete_t); // Destroying delete
};
void TestFailedInit(int n) {
new FailedInit();
new FailedInit[n];
new(1.0f) FailedInitOveraligned();
new(1.0f) FailedInitOveraligned[10];
new FailedInitDestroyingDelete();
}
// --- non-allocating placement new ---
namespace std {
typedef unsigned long size_t;
struct nothrow_t {};
extern const nothrow_t nothrow;
}
void* operator new (std::size_t size, void* ptr) noexcept;
void* operator new[](std::size_t size, void* ptr) noexcept;
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
int overloadedNew() {
char buf[sizeof(int)];
new(&buf[0]) int(5);
int five = *(int*)buf;
new(buf) int[1];
*(int*)buf = 4;
new(std::nothrow) int(3); // memory leak
new(std::nothrow) int[2]; // memory leak
return five;
}
void multidimensionalNew(int x, int y) {
auto p1 = new char[x][10];
auto p2 = new char[20][20];
auto p3 = new char[x][30][30];
}
void directOperatorCall() {
void *ptr;
ptr = operator new(sizeof(int));
operator delete(ptr);
}
void *malloc(size_t);
typedef int* ptr_int;
void testMalloc(size_t count) {
const volatile int *i = (const volatile int *) malloc(5);
ptr_int i2 = (ptr_int) malloc(5 * sizeof(int));
volatile long *l = (long *) malloc(count);
l = (long *) malloc(count * sizeof(int));
const char* c = (const char *) malloc(count * sizeof(int) + 1);
void * v = (void *) malloc(((int) count) * sizeof(void *));
malloc(sizeof(void *) * sizeof(int));
}