authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-11-10 01:38:41+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-11-10 06:51:48+00:00
log3f10b3ee1eaca13d8edbdebeae8cd50d40c095c0
tree0c7cf428b569626b1e3502fb2417cbcc70dc3e64
parente9b3fcaa4315a9c0c1d916a23267728d4d9ae550

Sema: do not allow comptime-only pointer fields in packed structs


2 files changed, 22 insertions(+), 8 deletions(-)

src/Sema.zig+14-8
......@@ -20923,7 +20923,7 @@ fn zirReify(
2092320923 break :msg msg;
2092420924 };
2092520925 return sema.failWithOwnedErrorMsg(block, msg);
20926 } else if (layout == .Packed and !(validatePackedType(field_ty, mod))) {
20926 } else if (layout == .Packed and !try sema.validatePackedType(field_ty)) {
2092720927 const msg = msg: {
2092820928 const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
2092920929 errdefer msg.destroy(gpa);
......@@ -21290,7 +21290,7 @@ fn reifyStruct(
2129021290 break :msg msg;
2129121291 };
2129221292 return sema.failWithOwnedErrorMsg(block, msg);
21293 } else if (layout == .Packed and !(validatePackedType(field_ty, mod))) {
21293 } else if (layout == .Packed and !try sema.validatePackedType(field_ty)) {
2129421294 const msg = msg: {
2129521295 const msg = try sema.errMsg(block, src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
2129621296 errdefer msg.destroy(gpa);
......@@ -25663,8 +25663,9 @@ fn explainWhyTypeIsNotExtern(
2566325663}
2566425664
2566525665/// Returns true if `ty` is allowed in packed types.
25666/// Does *NOT* require `ty` to be resolved in any way.
25667fn validatePackedType(ty: Type, mod: *Module) bool {
25666/// Does not require `ty` to be resolved in any way, but may resolve whether it is comptime-only.
25667fn validatePackedType(sema: *Sema, ty: Type) !bool {
25668 const mod = sema.mod;
2566825669 switch (ty.zigTypeTag(mod)) {
2566925670 .Type,
2567025671 .ComptimeFloat,
......@@ -25689,7 +25690,7 @@ fn validatePackedType(ty: Type, mod: *Module) bool {
2568925690 .Vector,
2569025691 .Enum,
2569125692 => return true,
25692 .Pointer => return !ty.isSlice(mod),
25693 .Pointer => return !ty.isSlice(mod) and !try sema.typeRequiresComptime(ty),
2569325694 .Struct, .Union => return ty.containerLayout(mod) == .Packed,
2569425695 }
2569525696}
......@@ -25724,7 +25725,12 @@ fn explainWhyTypeIsNotPacked(
2572425725 .Optional,
2572525726 .Array,
2572625727 => try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}),
25727 .Pointer => try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{}),
25728 .Pointer => if (ty.isSlice(mod)) {
25729 try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
25730 } else {
25731 try mod.errNoteNonLazy(src_loc, msg, "comptime-only pointer has no guaranteed in-memory representation", .{});
25732 try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
25733 },
2572825734 .Fn => {
2572925735 try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{});
2573025736 try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{});
......@@ -35890,7 +35896,7 @@ fn semaStructFields(
3589035896 };
3589135897 return sema.failWithOwnedErrorMsg(&block_scope, msg);
3589235898 },
35893 .Packed => if (!validatePackedType(field_ty, mod)) {
35899 .Packed => if (!try sema.validatePackedType(field_ty)) {
3589435900 const msg = msg: {
3589535901 const ty_src = mod.fieldSrcLoc(decl_index, .{
3589635902 .index = field_i,
......@@ -36443,7 +36449,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
3644336449 break :msg msg;
3644436450 };
3644536451 return sema.failWithOwnedErrorMsg(&block_scope, msg);
36446 } else if (layout == .Packed and !validatePackedType(field_ty, mod)) {
36452 } else if (layout == .Packed and !try sema.validatePackedType(field_ty)) {
3644736453 const msg = msg: {
3644836454 const ty_src = mod.fieldSrcLoc(union_type.decl, .{
3644936455 .index = field_i,
test/cases/compile_errors/packed_struct_with_fields_of_not_allowed_types.zig+8
......@@ -65,6 +65,11 @@ export fn entry12() void {
6565 x: packed struct { a: []u8 },
6666 });
6767}
68export fn entry13() void {
69 _ = @sizeOf(packed struct {
70 x: *type,
71 });
72}
6873
6974// error
7075// backend=llvm
......@@ -89,3 +94,6 @@ export fn entry12() void {
8994// :38:12: note: use '*const ' to make a function pointer type
9095// :65:31: error: packed structs cannot contain fields of type '[]u8'
9196// :65:31: note: slices have no guaranteed in-memory representation
97// :70:12: error: packed structs cannot contain fields of type '*type'
98// :70:12: note: comptime-only pointer has no guaranteed in-memory representation
99// :70:12: note: types are not available at runtime