aboutsummaryrefslogtreecommitdiff
path: root/src/type.zig
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2023-09-21 02:00:52 +0100
committerAndrew Kelley <andrew@ziglang.org>2023-09-21 14:48:41 -0700
commit1b672e41c528b0aa225cbe07c61203d04b2d9034 (patch)
tree080cac4fbde495c9b216fac1cd67e84799740059 /src/type.zig
parentcd242b7440e11d9997c33296b3974dfb1fbd5d95 (diff)
downloadzig-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.zig18
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 => {},
}