aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2023-06-10 01:23:17 +0100
committermlugg <mlugg@mlugg.co.uk>2023-06-25 14:05:18 +0100
commit2611d97fb07e5cba5657f508e93f01d60a2379bd (patch)
treefb2259414179756f86f79d176283d621a63b3168 /src
parent3f04231600e7ec2e16f5fb33f2e81eea24bdc41b (diff)
downloadzig-2611d97fb07e5cba5657f508e93f01d60a2379bd.tar.gz
zig-2611d97fb07e5cba5657f508e93f01d60a2379bd.zip
Sema: copy pointer alignment to union field pointers
This implements the semantics as discussed in today's compiler meeting, where the alignment of pointers to fields of default-layout unions cannot exceed the field's alignment. Resolves: #15878
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index a638c4d04b..4403df671a 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -26060,6 +26060,7 @@ fn unionFieldPtr(
assert(unresolved_union_ty.zigTypeTag(mod) == .Union);
const union_ptr_ty = sema.typeOf(union_ptr);
+ const union_ptr_info = union_ptr_ty.ptrInfo(mod);
const union_ty = try sema.resolveTypeFields(unresolved_union_ty);
const union_obj = mod.typeToUnion(union_ty).?;
const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
@@ -26067,10 +26068,16 @@ fn unionFieldPtr(
const ptr_field_ty = try mod.ptrType(.{
.child = field.ty.toIntern(),
.flags = .{
- .is_const = !union_ptr_ty.ptrIsMutable(mod),
- .is_volatile = union_ptr_ty.isVolatilePtr(mod),
- .address_space = union_ptr_ty.ptrAddressSpace(mod),
- },
+ .is_const = union_ptr_info.flags.is_const,
+ .is_volatile = union_ptr_info.flags.is_volatile,
+ .address_space = union_ptr_info.flags.address_space,
+ .alignment = if (union_obj.layout == .Auto) blk: {
+ const union_align = union_ptr_info.flags.alignment.toByteUnitsOptional() orelse try sema.typeAbiAlignment(union_ty);
+ const field_align = try sema.unionFieldAlignment(field);
+ break :blk InternPool.Alignment.fromByteUnits(@min(union_align, field_align));
+ } else union_ptr_info.flags.alignment,
+ },
+ .packed_offset = union_ptr_info.packed_offset,
});
const enum_field_index = @as(u32, @intCast(union_obj.tag_ty.enumFieldIndex(field_name, mod).?));