diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2023-09-21 02:00:52 +0100 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-09-21 14:48:41 -0700 |
| commit | 1b672e41c528b0aa225cbe07c61203d04b2d9034 (patch) | |
| tree | 080cac4fbde495c9b216fac1cd67e84799740059 /src/type.zig | |
| parent | cd242b7440e11d9997c33296b3974dfb1fbd5d95 (diff) | |
| download | zig-1b672e41c528b0aa225cbe07c61203d04b2d9034.tar.gz zig-1b672e41c528b0aa225cbe07c61203d04b2d9034.zip | |
InternPool,Sema,type,llvm: alignment fixes
This changeset fixes the handling of alignment in several places. The
new rules are:
* `@alignOf(T)` where `T` is a runtime zero-bit type is at least 1,
maybe greater.
* Zero-bit fields in `extern` structs *do* force alignment, potentially
offsetting following fields.
* Zero-bit fields *do* have addresses within structs which can be
observed and are consistent with `@offsetOf`.
These are not necessarily all implemented correctly yet (see disabled
test), but this commit fixes all regressions compared to master, and
makes one new test pass.
Diffstat (limited to 'src/type.zig')
| -rw-r--r-- | src/type.zig | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/src/type.zig b/src/type.zig index 5a94f9c57a..067c38b6b0 100644 --- a/src/type.zig +++ b/src/type.zig @@ -833,7 +833,7 @@ pub const Type = struct { }; } - /// Returns `none` for 0-bit types. + /// Never returns `none`. Asserts that all necessary type resolution is already done. pub fn abiAlignment(ty: Type, mod: *Module) Alignment { return (ty.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; } @@ -878,10 +878,10 @@ pub const Type = struct { }; switch (ty.toIntern()) { - .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = .none }, + .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = .@"1" }, else => switch (ip.indexToKey(ty.toIntern())) { .int_type => |int_type| { - if (int_type.bits == 0) return AbiAlignmentAdvanced{ .scalar = .none }; + if (int_type.bits == 0) return AbiAlignmentAdvanced{ .scalar = .@"1" }; return .{ .scalar = intAbiAlignment(int_type.bits, target) }; }, .ptr_type, .anyframe_type => { @@ -929,6 +929,7 @@ pub const Type = struct { .isize, .export_options, .extern_options, + .type_info, => return .{ .scalar = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8)), }, @@ -974,8 +975,7 @@ pub const Type = struct { .null, .undefined, .enum_literal, - .type_info, - => return .{ .scalar = .none }, + => return .{ .scalar = .@"1" }, .noreturn => unreachable, .generic_poison => unreachable, @@ -1010,11 +1010,9 @@ pub const Type = struct { }; }, .anon_struct_type => |tuple| { - var big_align: Alignment = .none; + var big_align: Alignment = .@"1"; for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { if (val != .none) continue; // comptime field - if (!(field_ty.toType().hasRuntimeBits(mod))) continue; - switch (try field_ty.toType().abiAlignmentAdvanced(mod, strat)) { .scalar => |field_align| big_align = big_align.max(field_align), .val => switch (strat) { @@ -1059,7 +1057,7 @@ pub const Type = struct { } } - var max_align: Alignment = .none; + var max_align: Alignment = .@"1"; if (union_obj.hasTag(ip)) max_align = union_obj.enum_tag_ty.toType().abiAlignment(mod); for (0..union_obj.field_names.len) |field_index| { const field_ty = union_obj.field_types.get(ip)[field_index].toType(); @@ -1172,7 +1170,7 @@ pub const Type = struct { .scalar = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8)), }, .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, mod, strat), - .NoReturn => return .{ .scalar = .none }, + .NoReturn => return .{ .scalar = .@"1" }, else => {}, } |
