Skip to content

Commit 70fc415

Browse files
committed
Do not use undefined for the ptr field of Allocator/Random instances
The use of undefined here meant that it was always unsafe/illegal to compare the ptr fields of Allocator/Random. However, this restriction is not mentioned anywhere and the ptr field *is* being compared in real code, e.g. `std.process.Child.collectOutput`, which can lead to undefined behavior in release modes (see ziglang#21756). There are two ways to address this: 1. Codify that comparing `ptr` is always illegal/unsafe, and remove all existing comparisons. 2. Set `ptr` to a legal dummy value, similar to the value returned by Allocator.alloc when a zero-length slice is requested. The first option seems like footgun central (at least until usage of `undefined` is fully safety-checked in safe modes), so I went with the second option. Closes ziglang#21756
1 parent 353647f commit 70fc415

File tree

5 files changed

+11
-11
lines changed

5 files changed

+11
-11
lines changed

lib/std/crypto/tlcsprng.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const posix = std.posix;
1212
/// We use this as a layer of indirection because global const pointers cannot
1313
/// point to thread-local variables.
1414
pub const interface: std.Random = .{
15-
.ptr = undefined,
15+
.ptr = mem.dummyPointer(*anyopaque),
1616
.fillFn = tlsCsprngFill,
1717
};
1818

lib/std/heap.zig

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ const CAllocator = struct {
150150
/// `malloc_usable_size` if available. For an allocator that directly calls
151151
/// `malloc`/`free`, see `raw_c_allocator`.
152152
pub const c_allocator = Allocator{
153-
.ptr = undefined,
153+
.ptr = mem.dummyPointer(*anyopaque),
154154
.vtable = &c_allocator_vtable,
155155
};
156156
const c_allocator_vtable = Allocator.VTable{
@@ -165,7 +165,7 @@ const c_allocator_vtable = Allocator.VTable{
165165
/// `ArenaAllocator` for example and is more optimal in such a case
166166
/// than `c_allocator`.
167167
pub const raw_c_allocator = Allocator{
168-
.ptr = undefined,
168+
.ptr = mem.dummyPointer(*anyopaque),
169169
.vtable = &raw_c_allocator_vtable,
170170
};
171171
const raw_c_allocator_vtable = Allocator.VTable{
@@ -231,17 +231,17 @@ pub const page_allocator = if (@hasDecl(root, "os") and
231231
root.os.heap.page_allocator
232232
else if (builtin.target.isWasm())
233233
Allocator{
234-
.ptr = undefined,
234+
.ptr = mem.dummyPointer(*anyopaque),
235235
.vtable = &WasmPageAllocator.vtable,
236236
}
237237
else if (builtin.target.os.tag == .plan9)
238238
Allocator{
239-
.ptr = undefined,
239+
.ptr = mem.dummyPointer(*anyopaque),
240240
.vtable = &SbrkAllocator(std.os.plan9.sbrk).vtable,
241241
}
242242
else
243243
Allocator{
244-
.ptr = undefined,
244+
.ptr = mem.dummyPointer(*anyopaque),
245245
.vtable = &PageAllocator.vtable,
246246
};
247247

@@ -251,7 +251,7 @@ else
251251
/// and wasm64 architectures.
252252
/// Until then, it is available here to play with.
253253
pub const wasm_allocator = Allocator{
254-
.ptr = undefined,
254+
.ptr = mem.dummyPointer(*anyopaque),
255255
.vtable = &std.heap.WasmAllocator.vtable,
256256
};
257257

lib/std/heap/WasmAllocator.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ fn allocBigPages(n: usize) usize {
158158
}
159159

160160
const test_ally = Allocator{
161-
.ptr = undefined,
161+
.ptr = mem.dummyPointer(*anyopaque),
162162
.vtable = &vtable,
163163
};
164164

lib/std/mem.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ pub fn alignAllocLen(full_len: usize, alloc_len: usize, len_align: u29) usize {
134134
}
135135

136136
const fail_allocator = Allocator{
137-
.ptr = undefined,
137+
.ptr = dummyPointer(*anyopaque),
138138
.vtable = &failAllocator_vtable,
139139
};
140140

lib/std/os/uefi/pool_allocator.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ const UefiPoolAllocator = struct {
6969
/// Supports the full Allocator interface, including alignment.
7070
/// For a direct call of `allocatePool`, see `raw_pool_allocator`.
7171
pub const pool_allocator = Allocator{
72-
.ptr = undefined,
72+
.ptr = mem.dummyPointer(*anyopaque),
7373
.vtable = &pool_allocator_vtable,
7474
};
7575

@@ -81,7 +81,7 @@ const pool_allocator_vtable = Allocator.VTable{
8181

8282
/// Asserts allocations are 8 byte aligned and calls `boot_services.allocatePool`.
8383
pub const raw_pool_allocator = Allocator{
84-
.ptr = undefined,
84+
.ptr = mem.dummyPointer(*anyopaque),
8585
.vtable = &raw_pool_allocator_table,
8686
};
8787

0 commit comments

Comments
 (0)