mirror of
https://github.com/ziglang/zig.git
synced 2025-12-28 00:53:18 +00:00
Sema: fix dependency loop regression on struct field alignment
This commit is contained in:
parent
2671aa9058
commit
5ea3de55c4
51
src/Sema.zig
51
src/Sema.zig
@ -34280,9 +34280,54 @@ pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
|
||||
}
|
||||
}
|
||||
|
||||
fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
|
||||
try sema.resolveTypeFields(ty);
|
||||
/// Resolve a struct's alignment only without triggering resolution of its layout.
|
||||
/// Asserts that the alignment is not yet resolved and the layout is non-packed.
|
||||
pub fn resolveStructAlignment(
|
||||
sema: *Sema,
|
||||
ty: InternPool.Index,
|
||||
struct_type: InternPool.Key.StructType,
|
||||
) CompileError!Alignment {
|
||||
const mod = sema.mod;
|
||||
const ip = &mod.intern_pool;
|
||||
const target = mod.getTarget();
|
||||
|
||||
assert(struct_type.flagsPtr(ip).alignment == .none);
|
||||
assert(struct_type.layout != .Packed);
|
||||
|
||||
if (struct_type.flagsPtr(ip).field_types_wip) {
|
||||
// We'll guess "pointer-aligned", if the struct has an
|
||||
// underaligned pointer field then some allocations
|
||||
// might require explicit alignment.
|
||||
//TODO write this bit and emit an error later if incorrect
|
||||
//struct_type.flagsPtr(ip).assumed_pointer_aligned = true;
|
||||
const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
|
||||
struct_type.flagsPtr(ip).alignment = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
try sema.resolveTypeFieldsStruct(ty, struct_type);
|
||||
|
||||
var result: Alignment = .@"1";
|
||||
|
||||
for (0..struct_type.field_types.len) |i| {
|
||||
if (struct_type.fieldIsComptime(ip, i)) continue;
|
||||
const field_ty = struct_type.field_types.get(ip)[i].toType();
|
||||
if (try sema.typeRequiresComptime(field_ty)) continue;
|
||||
if (try sema.typeHasRuntimeBits(field_ty)) {
|
||||
const field_align = try sema.structFieldAlignment(
|
||||
struct_type.fieldAlign(ip, i),
|
||||
field_ty,
|
||||
struct_type.layout,
|
||||
);
|
||||
result = result.max(field_align);
|
||||
}
|
||||
}
|
||||
|
||||
struct_type.flagsPtr(ip).alignment = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
|
||||
const mod = sema.mod;
|
||||
const ip = &mod.intern_pool;
|
||||
const struct_type = mod.typeToStruct(ty) orelse return;
|
||||
@ -34290,6 +34335,8 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
|
||||
if (struct_type.haveLayout(ip))
|
||||
return;
|
||||
|
||||
try sema.resolveTypeFields(ty);
|
||||
|
||||
if (struct_type.layout == .Packed) {
|
||||
try semaBackingIntType(mod, struct_type);
|
||||
return;
|
||||
|
||||
24
src/type.zig
24
src/type.zig
@ -201,7 +201,7 @@ pub const Type = struct {
|
||||
info.flags.alignment
|
||||
else
|
||||
info.child.toType().abiAlignment(mod);
|
||||
try writer.print("align({d}", .{alignment});
|
||||
try writer.print("align({d}", .{alignment.toByteUnits(0)});
|
||||
|
||||
if (info.packed_offset.bit_offset != 0 or info.packed_offset.host_size != 0) {
|
||||
try writer.print(":{d}:{d}", .{
|
||||
@ -992,30 +992,22 @@ pub const Type = struct {
|
||||
},
|
||||
.eager => {},
|
||||
}
|
||||
assert(struct_type.backingIntType(ip).* != .none);
|
||||
return .{ .scalar = struct_type.backingIntType(ip).toType().abiAlignment(mod) };
|
||||
}
|
||||
|
||||
const flags = struct_type.flagsPtr(ip).*;
|
||||
if (flags.layout_resolved) return .{ .scalar = flags.alignment };
|
||||
if (flags.alignment != .none) return .{ .scalar = flags.alignment };
|
||||
|
||||
switch (strat) {
|
||||
.eager => unreachable, // struct layout not resolved
|
||||
.sema => |sema| {
|
||||
if (flags.field_types_wip) {
|
||||
// We'll guess "pointer-aligned", if the struct has an
|
||||
// underaligned pointer field then some allocations
|
||||
// might require explicit alignment.
|
||||
return .{ .scalar = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8)) };
|
||||
}
|
||||
try sema.resolveTypeLayout(ty);
|
||||
return .{ .scalar = struct_type.flagsPtr(ip).alignment };
|
||||
return switch (strat) {
|
||||
.eager => unreachable, // struct alignment not resolved
|
||||
.sema => |sema| .{
|
||||
.scalar = try sema.resolveStructAlignment(ty.toIntern(), struct_type),
|
||||
},
|
||||
.lazy => return .{ .val = (try mod.intern(.{ .int = .{
|
||||
.lazy => .{ .val = (try mod.intern(.{ .int = .{
|
||||
.ty = .comptime_int_type,
|
||||
.storage = .{ .lazy_align = ty.toIntern() },
|
||||
} })).toValue() },
|
||||
}
|
||||
};
|
||||
},
|
||||
.anon_struct_type => |tuple| {
|
||||
var big_align: Alignment = .none;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user