Sema: do not allow comptime-only pointer fields in packed structs
This commit is contained in:
22
src/Sema.zig
22
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,
|
||||
|
||||
@@ -65,6 +65,11 @@ export fn entry12() void {
|
||||
x: packed struct { a: []u8 },
|
||||
});
|
||||
}
|
||||
export fn entry13() void {
|
||||
_ = @sizeOf(packed struct {
|
||||
x: *type,
|
||||
});
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
@@ -89,3 +94,6 @@ export fn entry12() void {
|
||||
// :38:12: note: use '*const ' to make a function pointer type
|
||||
// :65:31: error: packed structs cannot contain fields of type '[]u8'
|
||||
// :65:31: note: slices have no guaranteed in-memory representation
|
||||
// :70:12: error: packed structs cannot contain fields of type '*type'
|
||||
// :70:12: note: comptime-only pointer has no guaranteed in-memory representation
|
||||
// :70:12: note: types are not available at runtime
|
||||
|
||||
Reference in New Issue
Block a user