Commit f83fe2714b
Changed files (3)
src
test
behavior
src/Sema/comptime_ptr_access.zig
@@ -65,6 +65,15 @@ pub fn storeComptimePtr(
const zcu = pt.zcu;
const ptr_info = ptr.typeOf(zcu).ptrInfo(zcu);
assert(store_val.typeOf(zcu).toIntern() == ptr_info.child);
+
+ {
+ const store_ty: Type = .fromInterned(ptr_info.child);
+ if (!try store_ty.comptimeOnlySema(pt) and !try store_ty.hasRuntimeBitsIgnoreComptimeSema(pt)) {
+ // zero-bit store; nothing to do
+ return .success;
+ }
+ }
+
// TODO: host size for vectors is terrible
const host_bits = switch (ptr_info.flags.vector_index) {
.none => ptr_info.packed_offset.host_size * 8,
src/Type.zig
@@ -1637,10 +1637,7 @@ pub fn bitSizeInner(
const len = array_type.lenIncludingSentinel();
if (len == 0) return 0;
const elem_ty = Type.fromInterned(array_type.child);
- const elem_size = @max(
- (try elem_ty.abiAlignmentInner(strat_lazy, zcu, tid)).scalar.toByteUnits() orelse 0,
- (try elem_ty.abiSizeInner(strat_lazy, zcu, tid)).scalar,
- );
+ const elem_size = (try elem_ty.abiSizeInner(strat_lazy, zcu, tid)).scalar;
if (elem_size == 0) return 0;
const elem_bit_size = try elem_ty.bitSizeInner(strat, zcu, tid);
return (len - 1) * 8 * elem_size + elem_bit_size;
test/behavior/comptime_memory.zig
@@ -515,3 +515,66 @@ fn fieldPtrTest() u32 {
test "pointer in aggregate field can mutate comptime state" {
try comptime std.testing.expect(fieldPtrTest() == 2);
}
+
+test "comptime store of extern struct with void field" {
+ comptime {
+ var x: extern struct { a: u8, b: void } = undefined;
+ x = .{ .a = 123, .b = {} };
+ std.debug.assert(x.a == 123);
+ }
+}
+
+test "comptime store of extern struct with void field into array" {
+ comptime {
+ var x: [3]extern struct { a: u8, b: void } = undefined;
+ x[1] = .{ .a = 123, .b = {} };
+ std.debug.assert(x[1].a == 123);
+ }
+}
+
+test "comptime store of packed struct with void field" {
+ comptime {
+ var x: packed struct { a: u8, b: void } = undefined;
+ x = .{ .a = 123, .b = {} };
+ std.debug.assert(x.a == 123);
+ }
+}
+
+test "comptime store of packed struct with void field into array" {
+ comptime {
+ var x: [3]packed struct { a: u8, b: void } = undefined;
+ x[1] = .{ .a = 123, .b = {} };
+ std.debug.assert(x[1].a == 123);
+ }
+}
+
+test "comptime store of reinterpreted zero-bit type" {
+ const S = struct {
+ fn doTheTest(comptime T: type) void {
+ comptime var buf: T = undefined;
+ const ptr: *void = @ptrCast(&buf);
+ ptr.* = {};
+ }
+ };
+ S.doTheTest(void);
+ S.doTheTest(u0);
+ S.doTheTest([0]u8);
+ S.doTheTest([1]u0);
+ S.doTheTest([5]u0);
+ S.doTheTest([5]void);
+ S.doTheTest(packed struct(u0) {});
+}
+
+test "comptime store to extern struct reinterpreted as byte array" {
+ const T = extern struct {
+ x: u32,
+ y: f32,
+ z: [2]void,
+ };
+ comptime var val: T = undefined;
+
+ const bytes: *[@sizeOf(T)]u8 = @ptrCast(&val);
+ @memset(bytes, 0);
+
+ comptime std.debug.assert(val.x == 0);
+}