aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-12-28 23:10:48 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-12-28 23:22:09 -0700
commitefb7148a4574c608b21359fcbf2edf06afdb5e0c (patch)
tree23e47a49f95e60ea315603407bd5793310978c62 /src/Module.zig
parent91619cdf57f54accbdbb3ff616856eaf79b537a3 (diff)
downloadzig-efb7148a4574c608b21359fcbf2edf06afdb5e0c.tar.gz
zig-efb7148a4574c608b21359fcbf2edf06afdb5e0c.zip
Sema: more union fixes
* `Module.Union.getLayout`: fixes to support components of the union being 0 bits. * Implement `@typeInfo` for unions. * Add missing calls to `resolveTypeFields`. * Fix explicitly-provided union tag types passing a `Zir.Inst.Ref` where an `Air.Inst.Ref` was expected. We don't have any type safety for this; these typess are aliases. * Fix explicitly-provided `union(enum)` tag Values allocated to the wrong arena.
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig19
1 files changed, 10 insertions, 9 deletions
diff --git a/src/Module.zig b/src/Module.zig
index a1f804c282..ef01aa2c54 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -1104,9 +1104,9 @@ pub const Union = struct {
pub fn getLayout(u: Union, target: Target, have_tag: bool) Layout {
assert(u.status == .have_layout);
- var most_aligned_field: usize = undefined;
+ var most_aligned_field: u32 = undefined;
var most_aligned_field_size: u64 = undefined;
- var biggest_field: usize = undefined;
+ var biggest_field: u32 = undefined;
var payload_size: u64 = 0;
var payload_align: u32 = 0;
for (u.fields.values()) |field, i| {
@@ -1122,20 +1122,21 @@ pub const Union = struct {
const field_size = field.ty.abiSize(target);
if (field_size > payload_size) {
payload_size = field_size;
- biggest_field = i;
+ biggest_field = @intCast(u32, i);
}
if (field_align > payload_align) {
payload_align = field_align;
- most_aligned_field = i;
+ most_aligned_field = @intCast(u32, i);
most_aligned_field_size = field_size;
}
}
+ payload_align = @maximum(payload_align, 1);
if (!have_tag) return .{
.abi_size = std.mem.alignForwardGeneric(u64, payload_size, payload_align),
.abi_align = payload_align,
- .most_aligned_field = @intCast(u32, most_aligned_field),
+ .most_aligned_field = most_aligned_field,
.most_aligned_field_size = most_aligned_field_size,
- .biggest_field = @intCast(u32, biggest_field),
+ .biggest_field = biggest_field,
.payload_size = payload_size,
.payload_align = payload_align,
.tag_align = 0,
@@ -1144,7 +1145,7 @@ pub const Union = struct {
// Put the tag before or after the payload depending on which one's
// alignment is greater.
const tag_size = u.tag_ty.abiSize(target);
- const tag_align = u.tag_ty.abiAlignment(target);
+ const tag_align = @maximum(1, u.tag_ty.abiAlignment(target));
var size: u64 = 0;
if (tag_align >= payload_align) {
// {Tag, Payload}
@@ -1162,9 +1163,9 @@ pub const Union = struct {
return .{
.abi_size = size,
.abi_align = @maximum(tag_align, payload_align),
- .most_aligned_field = @intCast(u32, most_aligned_field),
+ .most_aligned_field = most_aligned_field,
.most_aligned_field_size = most_aligned_field_size,
- .biggest_field = @intCast(u32, biggest_field),
+ .biggest_field = biggest_field,
.payload_size = payload_size,
.payload_align = payload_align,
.tag_align = tag_align,