authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-10-19 23:25:29-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-10-20 11:56:52-07:00
logbadf016b83583df98ac9c56e4147235fb9bd7f8c
tree423f4ff5e0704c57e178ec441c906b30aaa98b78
parent3c0e8b34d76d7c081a5d8b1f2d060fe6735e8d12

InternPool: include sentinel when checking for repeating elems

Without including the sentinel in this check, a sentinel terminated array with repeated elements up to the sentinel would get interned as a repeated aggregate, meaning that when the value would get uninterned for mutation, all values including the sentinel would get set to the repeated element, even though the sentinel is *not* repeated. Without this fix, `x.a[2]` in the added test case would end up with the value 50. Closes #37339

2 files changed, 13 insertions(+), 1 deletions(-)

src/InternPool.zig+1-1
...@@ -7901,7 +7901,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:...@@ -7901,7 +7901,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
7901 switch (aggregate.storage) {7901 switch (aggregate.storage) {
7902 .bytes => |bytes| for (bytes.toSlice(len, ip)[1..]) |byte|7902 .bytes => |bytes| for (bytes.toSlice(len, ip)[1..]) |byte|
7903 if (byte != bytes.at(0, ip)) break :repeated,7903 if (byte != bytes.at(0, ip)) break :repeated,
7904 .elems => |elems| for (elems[1..@intCast(len)]) |elem|7904 .elems => |elems| for (elems[1..@intCast(len_including_sentinel)]) |elem|
7905 if (elem != elems[0]) break :repeated,7905 if (elem != elems[0]) break :repeated,
7906 .repeated_elem => {},7906 .repeated_elem => {},
7907 }7907 }
test/behavior/comptime_memory.zig+12
...@@ -606,3 +606,15 @@ test "reinterpret pointer as optional pointer via double-pointer coercion" {...@@ -606,3 +606,15 @@ test "reinterpret pointer as optional pointer via double-pointer coercion" {
606 comptime assert(@TypeOf(loaded) == ?*anyopaque);606 comptime assert(@TypeOf(loaded) == ?*anyopaque);
607 comptime assert(@intFromPtr(loaded) == 0x1000);607 comptime assert(@intFromPtr(loaded) == 0x1000);
608}608}
609
610test "comptime store to sentinel-terminated array in an extern struct" {
611 comptime {
612 var x: extern struct {
613 a: [2:0]u8 = @splat(50),
614 } = .{};
615 x.a[0] = 100;
616 assert(x.a[0] == 100);
617 assert(x.a[1] == 50);
618 assert(x.a[2] == 0);
619 }
620}