mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
Sema: compile error on reifying align(0) struct fields
This commit is contained in:
parent
a00edbd52d
commit
17330867eb
4 changed files with 87 additions and 60 deletions
63
src/Sema.zig
63
src/Sema.zig
|
|
@ -2649,7 +2649,13 @@ pub fn analyzeAsAlign(
|
|||
src: LazySrcLoc,
|
||||
air_ref: Air.Inst.Ref,
|
||||
) !Alignment {
|
||||
const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty, .{ .simple = .@"align" });
|
||||
const alignment_big = try sema.analyzeAsInt(
|
||||
block,
|
||||
src,
|
||||
air_ref,
|
||||
align_ty,
|
||||
.{ .simple = .@"align" },
|
||||
);
|
||||
return sema.validateAlign(block, src, alignment_big);
|
||||
}
|
||||
|
||||
|
|
@ -18807,7 +18813,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
|||
const abi_align: Alignment = if (inst_data.flags.has_align) blk: {
|
||||
const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);
|
||||
extra_i += 1;
|
||||
const coerced = try sema.coerce(block, .u32, try sema.resolveInst(ref), align_src);
|
||||
const coerced = try sema.coerce(block, align_ty, try sema.resolveInst(ref), align_src);
|
||||
const val = try sema.resolveConstDefinedValue(block, align_src, coerced, .{ .simple = .@"align" });
|
||||
// Check if this happens to be the lazy alignment of our element type, in
|
||||
// which case we can make this 0 without resolving it.
|
||||
|
|
@ -20325,15 +20331,11 @@ fn zirReify(
|
|||
try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls),
|
||||
).?);
|
||||
|
||||
if (!try sema.intFitsInType(alignment_val, .u32, null)) {
|
||||
return sema.fail(block, src, "alignment must fit in 'u32'", .{});
|
||||
if (!try sema.intFitsInType(alignment_val, align_ty, null)) {
|
||||
return sema.fail(block, src, "alignment must fit in '{}'", .{align_ty.fmt(pt)});
|
||||
}
|
||||
|
||||
const alignment_val_int = try alignment_val.toUnsignedIntSema(pt);
|
||||
if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {
|
||||
return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int});
|
||||
}
|
||||
const abi_align = Alignment.fromByteUnits(alignment_val_int);
|
||||
const abi_align = try sema.validateAlign(block, src, alignment_val_int);
|
||||
|
||||
const elem_ty = child_val.toType();
|
||||
if (abi_align != .none) {
|
||||
|
|
@ -21017,11 +21019,7 @@ fn reifyUnion(
|
|||
field_ty.* = field_type_val.toIntern();
|
||||
if (any_aligns) {
|
||||
const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);
|
||||
if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
|
||||
// TODO: better source location
|
||||
return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
|
||||
}
|
||||
field_aligns[field_idx] = Alignment.fromByteUnits(byte_align);
|
||||
field_aligns[field_idx] = try sema.validateAlign(block, src, byte_align);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -21062,11 +21060,7 @@ fn reifyUnion(
|
|||
field_ty.* = field_type_val.toIntern();
|
||||
if (any_aligns) {
|
||||
const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt);
|
||||
if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
|
||||
// TODO: better source location
|
||||
return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
|
||||
}
|
||||
field_aligns[field_idx] = Alignment.fromByteUnits(byte_align);
|
||||
field_aligns[field_idx] = try sema.validateAlign(block, src, byte_align);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -21266,7 +21260,6 @@ fn reifyStruct(
|
|||
|
||||
var any_comptime_fields = false;
|
||||
var any_default_inits = false;
|
||||
var any_aligned_fields = false;
|
||||
|
||||
for (0..fields_len) |field_idx| {
|
||||
const field_info = try fields_val.elemValue(pt, field_idx);
|
||||
|
|
@ -21301,11 +21294,6 @@ fn reifyStruct(
|
|||
|
||||
if (field_is_comptime) any_comptime_fields = true;
|
||||
if (field_default_value != .none) any_default_inits = true;
|
||||
switch (try field_alignment_val.orderAgainstZeroSema(pt)) {
|
||||
.eq => {},
|
||||
.gt => any_aligned_fields = true,
|
||||
.lt => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
const tracked_inst = try block.trackZir(inst);
|
||||
|
|
@ -21317,7 +21305,7 @@ fn reifyStruct(
|
|||
.requires_comptime = .unknown,
|
||||
.any_comptime_fields = any_comptime_fields,
|
||||
.any_default_inits = any_default_inits,
|
||||
.any_aligned_fields = any_aligned_fields,
|
||||
.any_aligned_fields = true,
|
||||
.inits_resolved = true,
|
||||
.key = .{ .reified = .{
|
||||
.zir_index = tracked_inst,
|
||||
|
|
@ -21361,21 +21349,14 @@ fn reifyStruct(
|
|||
return sema.fail(block, src, "duplicate struct field name {f}", .{field_name.fmt(ip)});
|
||||
}
|
||||
|
||||
if (any_aligned_fields) {
|
||||
if (!try sema.intFitsInType(field_alignment_val, .u32, null)) {
|
||||
return sema.fail(block, src, "alignment must fit in 'u32'", .{});
|
||||
}
|
||||
|
||||
const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
|
||||
if (byte_align == 0) {
|
||||
if (layout != .@"packed") {
|
||||
struct_type.field_aligns.get(ip)[field_idx] = .none;
|
||||
}
|
||||
} else {
|
||||
if (layout == .@"packed") return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
|
||||
if (!math.isPowerOfTwo(byte_align)) return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
|
||||
struct_type.field_aligns.get(ip)[field_idx] = Alignment.fromNonzeroByteUnits(byte_align);
|
||||
}
|
||||
if (!try sema.intFitsInType(field_alignment_val, align_ty, null)) {
|
||||
return sema.fail(block, src, "alignment must fit in '{f}'", .{align_ty.fmt(pt)});
|
||||
}
|
||||
const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
|
||||
if (layout == .@"packed") {
|
||||
if (byte_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
|
||||
} else {
|
||||
struct_type.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);
|
||||
}
|
||||
|
||||
const field_is_comptime = field_is_comptime_val.toBool();
|
||||
|
|
|
|||
|
|
@ -1,52 +1,98 @@
|
|||
pub var global_var: i32 align(0) = undefined;
|
||||
var global_var: i32 align(0) = undefined;
|
||||
|
||||
pub export fn a() void {
|
||||
export fn a() void {
|
||||
_ = &global_var;
|
||||
}
|
||||
|
||||
pub extern var extern_var: i32 align(0);
|
||||
extern var extern_var: i32 align(0);
|
||||
|
||||
pub export fn b() void {
|
||||
export fn b() void {
|
||||
_ = &extern_var;
|
||||
}
|
||||
|
||||
pub export fn c() align(0) void {}
|
||||
export fn c() align(0) void {}
|
||||
|
||||
pub export fn d() void {
|
||||
export fn d() void {
|
||||
_ = *align(0) fn () i32;
|
||||
}
|
||||
|
||||
pub export fn e() void {
|
||||
export fn e() void {
|
||||
var local_var: i32 align(0) = undefined;
|
||||
_ = &local_var;
|
||||
}
|
||||
|
||||
pub export fn f() void {
|
||||
export fn f() void {
|
||||
_ = *align(0) i32;
|
||||
}
|
||||
|
||||
pub export fn g() void {
|
||||
export fn g() void {
|
||||
_ = []align(0) i32;
|
||||
}
|
||||
|
||||
pub export fn h() void {
|
||||
export fn h() void {
|
||||
_ = struct { field: i32 align(0) };
|
||||
}
|
||||
|
||||
pub export fn i() void {
|
||||
export fn i() void {
|
||||
_ = union { field: i32 align(0) };
|
||||
}
|
||||
|
||||
export fn j() void {
|
||||
_ = @Type(.{ .@"struct" = .{
|
||||
.layout = .auto,
|
||||
.fields = &.{.{
|
||||
.name = "test",
|
||||
.type = u32,
|
||||
.default_value_ptr = null,
|
||||
.is_comptime = false,
|
||||
.alignment = 0,
|
||||
}},
|
||||
.decls = &.{},
|
||||
.is_tuple = false,
|
||||
} });
|
||||
}
|
||||
|
||||
export fn k() void {
|
||||
_ = @Type(.{ .pointer = .{
|
||||
.size = .one,
|
||||
.is_const = false,
|
||||
.is_volatile = false,
|
||||
.alignment = 0,
|
||||
.address_space = .generic,
|
||||
.child = u32,
|
||||
.is_allowzero = false,
|
||||
.sentinel_ptr = null,
|
||||
} });
|
||||
}
|
||||
|
||||
export fn l() void {
|
||||
_ = @Type(.{ .@"struct" = .{
|
||||
.layout = .@"packed",
|
||||
.fields = &.{.{
|
||||
.name = "test",
|
||||
.type = u32,
|
||||
.default_value_ptr = null,
|
||||
.is_comptime = false,
|
||||
.alignment = 8,
|
||||
}},
|
||||
.decls = &.{},
|
||||
.is_tuple = false,
|
||||
} });
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :1:31: error: alignment must be >= 1
|
||||
// :7:38: error: alignment must be >= 1
|
||||
// :13:25: error: alignment must be >= 1
|
||||
// :1:27: error: alignment must be >= 1
|
||||
// :7:34: error: alignment must be >= 1
|
||||
// :13:21: error: alignment must be >= 1
|
||||
// :16:16: error: alignment must be >= 1
|
||||
// :20:30: error: alignment must be >= 1
|
||||
// :25:16: error: alignment must be >= 1
|
||||
// :29:17: error: alignment must be >= 1
|
||||
// :33:35: error: alignment must be >= 1
|
||||
// :37:34: error: alignment must be >= 1
|
||||
// :41:9: error: alignment can only be 0 on packed struct fields
|
||||
// :56:9: error: alignment must be >= 1
|
||||
// :69:9: error: alignment in a packed struct field must be set to 0
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@ export fn entry2() void {
|
|||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:22: error: expected type 'u32', found 'bool'
|
||||
// :6:21: error: fractional component prevents float value '12.34' from coercion to type 'u32'
|
||||
// :2:22: error: expected type 'u29', found 'bool'
|
||||
// :6:21: error: fractional component prevents float value '12.34' from coercion to type 'u29'
|
||||
|
|
|
|||
|
|
@ -43,6 +43,6 @@ comptime {
|
|||
|
||||
// error
|
||||
//
|
||||
// :2:9: error: alignment value '3' is not a power of two or zero
|
||||
// :14:9: error: alignment value '5' is not a power of two or zero
|
||||
// :30:9: error: alignment value '7' is not a power of two or zero
|
||||
// :2:9: error: alignment value '3' is not a power of two
|
||||
// :14:9: error: alignment value '5' is not a power of two
|
||||
// :30:9: error: alignment value '7' is not a power of two
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue