diff options
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 41e74eae07..2f19557a17 100644 --- a/src/Sema.zig +++ b/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; |
