authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-12 23:45:22+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-14 20:27:49+00:00
log27274d4fdea8061d7afacbb2b179fd49fbaca125
treec822f893fc11d549384a3ba3942aa280011b69b3
parentaffe45b31f48d216a407f060c49df6bad82ad30c

Type: `struct {}` does not have a well-defined layout

`Type.hasWellDefinedLayout` was in disagreement with pointer loading logic about auto-layout structs with zero fields, `struct {}`. For consistency, these types should not have a well-defined layout. This is technically a breaking change.

2 files changed, 12 insertions(+), 5 deletions(-)

src/Type.zig+1-5
...@@ -723,11 +723,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {...@@ -723,11 +723,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
723 .generic_poison,723 .generic_poison,
724 => false,724 => false,
725 },725 },
726 .struct_type => {726 .struct_type => ip.loadStructType(ty.toIntern()).layout != .auto,
727 const struct_type = ip.loadStructType(ty.toIntern());
728 // Struct with no fields have a well-defined layout of no bits.
729 return struct_type.layout != .auto or struct_type.field_types.len == 0;
730 },
731 .union_type => {727 .union_type => {
732 const union_type = ip.loadUnionType(ty.toIntern());728 const union_type = ip.loadUnionType(ty.toIntern());
733 return switch (union_type.flagsUnordered(ip).runtime_tag) {729 return switch (union_type.flagsUnordered(ip).runtime_tag) {
test/cases/compile_errors/dereference_bad_pointer_via_array_mul.zig created+11
...@@ -0,0 +1,11 @@
1const A = struct {};
2const B = struct {};
3comptime {
4 const val: [1]A = .{.{}};
5 const ptr: *const [1]B = @ptrCast(&val);
6 _ = ptr ** 2;
7}
8
9// error
10//
11// :6:9: error: comptime dereference requires '[1]tmp.B' to have a well-defined layout