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(...@@ -20923,7 +20923,7 @@ fn zirReify(
20923 break :msg msg;20923 break :msg msg;
20924 };20924 };
20925 return sema.failWithOwnedErrorMsg(block, msg);20925 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)) {
20927 const msg = msg: {20927 const msg = msg: {
20928 const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});20928 const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
20929 errdefer msg.destroy(gpa);20929 errdefer msg.destroy(gpa);
...@@ -21290,7 +21290,7 @@ fn reifyStruct(...@@ -21290,7 +21290,7 @@ fn reifyStruct(
21290 break :msg msg;21290 break :msg msg;
21291 };21291 };
21292 return sema.failWithOwnedErrorMsg(block, msg);21292 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)) {
21294 const msg = msg: {21294 const msg = msg: {
21295 const msg = try sema.errMsg(block, src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});21295 const msg = try sema.errMsg(block, src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
21296 errdefer msg.destroy(gpa);21296 errdefer msg.destroy(gpa);
...@@ -25663,8 +25663,9 @@ fn explainWhyTypeIsNotExtern(...@@ -25663,8 +25663,9 @@ fn explainWhyTypeIsNotExtern(
25663}25663}
2566425664
25665/// Returns true if `ty` is allowed in packed types.25665/// Returns true if `ty` is allowed in packed types.
25666/// Does *NOT* require `ty` to be resolved in any way.25666/// Does not require `ty` to be resolved in any way, but may resolve whether it is comptime-only.
25667fn validatePackedType(ty: Type, mod: *Module) bool {25667fn validatePackedType(sema: *Sema, ty: Type) !bool {
25668 const mod = sema.mod;
25668 switch (ty.zigTypeTag(mod)) {25669 switch (ty.zigTypeTag(mod)) {
25669 .Type,25670 .Type,
25670 .ComptimeFloat,25671 .ComptimeFloat,
...@@ -25689,7 +25690,7 @@ fn validatePackedType(ty: Type, mod: *Module) bool {...@@ -25689,7 +25690,7 @@ fn validatePackedType(ty: Type, mod: *Module) bool {
25689 .Vector,25690 .Vector,
25690 .Enum,25691 .Enum,
25691 => return true,25692 => return true,
25692 .Pointer => return !ty.isSlice(mod),25693 .Pointer => return !ty.isSlice(mod) and !try sema.typeRequiresComptime(ty),
25693 .Struct, .Union => return ty.containerLayout(mod) == .Packed,25694 .Struct, .Union => return ty.containerLayout(mod) == .Packed,
25694 }25695 }
25695}25696}
...@@ -25724,7 +25725,12 @@ fn explainWhyTypeIsNotPacked(...@@ -25724,7 +25725,12 @@ fn explainWhyTypeIsNotPacked(
25724 .Optional,25725 .Optional,
25725 .Array,25726 .Array,
25726 => try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}),25727 => 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 },
25728 .Fn => {25734 .Fn => {
25729 try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{});25735 try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{});
25730 try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{});25736 try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{});
...@@ -35890,7 +35896,7 @@ fn semaStructFields(...@@ -35890,7 +35896,7 @@ fn semaStructFields(
35890 };35896 };
35891 return sema.failWithOwnedErrorMsg(&block_scope, msg);35897 return sema.failWithOwnedErrorMsg(&block_scope, msg);
35892 },35898 },
35893 .Packed => if (!validatePackedType(field_ty, mod)) {35899 .Packed => if (!try sema.validatePackedType(field_ty)) {
35894 const msg = msg: {35900 const msg = msg: {
35895 const ty_src = mod.fieldSrcLoc(decl_index, .{35901 const ty_src = mod.fieldSrcLoc(decl_index, .{
35896 .index = field_i,35902 .index = field_i,
...@@ -36443,7 +36449,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un...@@ -36443,7 +36449,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
36443 break :msg msg;36449 break :msg msg;
36444 };36450 };
36445 return sema.failWithOwnedErrorMsg(&block_scope, msg);36451 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)) {
36447 const msg = msg: {36453 const msg = msg: {
36448 const ty_src = mod.fieldSrcLoc(union_type.decl, .{36454 const ty_src = mod.fieldSrcLoc(union_type.decl, .{
36449 .index = field_i,36455 .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 {...@@ -65,6 +65,11 @@ export fn entry12() void {
65 x: packed struct { a: []u8 },65 x: packed struct { a: []u8 },
66 });66 });
67}67}
68export fn entry13() void {
69 _ = @sizeOf(packed struct {
70 x: *type,
71 });
72}
6873
69// error74// error
70// backend=llvm75// backend=llvm
...@@ -89,3 +94,6 @@ export fn entry12() void {...@@ -89,3 +94,6 @@ export fn entry12() void {
89// :38:12: note: use '*const ' to make a function pointer type94// :38:12: note: use '*const ' to make a function pointer type
90// :65:31: error: packed structs cannot contain fields of type '[]u8'95// :65:31: error: packed structs cannot contain fields of type '[]u8'
91// :65:31: note: slices have no guaranteed in-memory representation96// :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