diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2023-11-10 01:38:41 +0000 |
|---|---|---|
| committer | Matthew Lugg <mlugg@mlugg.co.uk> | 2023-11-10 06:51:48 +0000 |
| commit | 3f10b3ee1eaca13d8edbdebeae8cd50d40c095c0 (patch) | |
| tree | 0c7cf428b569626b1e3502fb2417cbcc70dc3e64 /src | |
| parent | e9b3fcaa4315a9c0c1d916a23267728d4d9ae550 (diff) | |
| download | zig-3f10b3ee1eaca13d8edbdebeae8cd50d40c095c0.tar.gz zig-3f10b3ee1eaca13d8edbdebeae8cd50d40c095c0.zip | |
Sema: do not allow comptime-only pointer fields in packed structs
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 4fbd80e23c..795f0c43fe 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -20923,7 +20923,7 @@ fn zirReify( break :msg msg; }; return sema.failWithOwnedErrorMsg(block, msg); - } else if (layout == .Packed and !(validatePackedType(field_ty, mod))) { + } else if (layout == .Packed and !try sema.validatePackedType(field_ty)) { const msg = msg: { const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)}); errdefer msg.destroy(gpa); @@ -21290,7 +21290,7 @@ fn reifyStruct( break :msg msg; }; return sema.failWithOwnedErrorMsg(block, msg); - } else if (layout == .Packed and !(validatePackedType(field_ty, mod))) { + } else if (layout == .Packed and !try sema.validatePackedType(field_ty)) { const msg = msg: { const msg = try sema.errMsg(block, src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); errdefer msg.destroy(gpa); @@ -25663,8 +25663,9 @@ fn explainWhyTypeIsNotExtern( } /// Returns true if `ty` is allowed in packed types. -/// Does *NOT* require `ty` to be resolved in any way. -fn validatePackedType(ty: Type, mod: *Module) bool { +/// Does not require `ty` to be resolved in any way, but may resolve whether it is comptime-only. +fn validatePackedType(sema: *Sema, ty: Type) !bool { + const mod = sema.mod; switch (ty.zigTypeTag(mod)) { .Type, .ComptimeFloat, @@ -25689,7 +25690,7 @@ fn validatePackedType(ty: Type, mod: *Module) bool { .Vector, .Enum, => return true, - .Pointer => return !ty.isSlice(mod), + .Pointer => return !ty.isSlice(mod) and !try sema.typeRequiresComptime(ty), .Struct, .Union => return ty.containerLayout(mod) == .Packed, } } @@ -25724,7 +25725,12 @@ fn explainWhyTypeIsNotPacked( .Optional, .Array, => try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}), - .Pointer => try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{}), + .Pointer => if (ty.isSlice(mod)) { + try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{}); + } else { + try mod.errNoteNonLazy(src_loc, msg, "comptime-only pointer has no guaranteed in-memory representation", .{}); + try sema.explainWhyTypeIsComptime(msg, src_loc, ty); + }, .Fn => { try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}); try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{}); @@ -35890,7 +35896,7 @@ fn semaStructFields( }; return sema.failWithOwnedErrorMsg(&block_scope, msg); }, - .Packed => if (!validatePackedType(field_ty, mod)) { + .Packed => if (!try sema.validatePackedType(field_ty)) { const msg = msg: { const ty_src = mod.fieldSrcLoc(decl_index, .{ .index = field_i, @@ -36443,7 +36449,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un break :msg msg; }; return sema.failWithOwnedErrorMsg(&block_scope, msg); - } else if (layout == .Packed and !validatePackedType(field_ty, mod)) { + } else if (layout == .Packed and !try sema.validatePackedType(field_ty)) { const msg = msg: { const ty_src = mod.fieldSrcLoc(union_type.decl, .{ .index = field_i, |
