aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKendall Condon <149842806+gooncreeper@users.noreply.github.com>2025-03-26 11:31:57 -0400
committerGitHub <noreply@github.com>2025-03-26 15:31:57 +0000
commitb4b1daf0012c3007b762df31028fa35f5f68bd09 (patch)
tree538226cddaca2ec6f7be5414f31133af4613ed1c
parentb84db311d90d722c206a7eea5464f46fd1b9e827 (diff)
downloadzig-b4b1daf0012c3007b762df31028fa35f5f68bd09.tar.gz
zig-b4b1daf0012c3007b762df31028fa35f5f68bd09.zip
Allocator.create: properly handle alignment for zero-sized types (#21864)
-rw-r--r--lib/std/heap.zig2
-rw-r--r--lib/std/mem/Allocator.zig5
2 files changed, 6 insertions, 1 deletions
diff --git a/lib/std/heap.zig b/lib/std/heap.zig
index f0ea8d0d46..3e7647abb6 100644
--- a/lib/std/heap.zig
+++ b/lib/std/heap.zig
@@ -593,6 +593,8 @@ pub fn testAllocator(base_allocator: mem.Allocator) !void {
const zero_bit_ptr = try allocator.create(u0);
zero_bit_ptr.* = 0;
allocator.destroy(zero_bit_ptr);
+ const zero_len_array = try allocator.create([0]u64);
+ allocator.destroy(zero_len_array);
const oversize = try allocator.alignedAlloc(u32, null, 5);
try testing.expect(oversize.len >= 5);
diff --git a/lib/std/mem/Allocator.zig b/lib/std/mem/Allocator.zig
index 9284e5ced3..c2f73096e8 100644
--- a/lib/std/mem/Allocator.zig
+++ b/lib/std/mem/Allocator.zig
@@ -150,7 +150,10 @@ pub inline fn rawFree(a: Allocator, memory: []u8, alignment: Alignment, ret_addr
/// Returns a pointer to undefined memory.
/// Call `destroy` with the result to free the memory.
pub fn create(a: Allocator, comptime T: type) Error!*T {
- if (@sizeOf(T) == 0) return @as(*T, @ptrFromInt(math.maxInt(usize)));
+ if (@sizeOf(T) == 0) {
+ const ptr = comptime std.mem.alignBackward(usize, math.maxInt(usize), @alignOf(T));
+ return @as(*T, @ptrFromInt(ptr));
+ }
const ptr: *T = @ptrCast(try a.allocBytesWithAlignment(@alignOf(T), @sizeOf(T), @returnAddress()));
return ptr;
}