diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2023-06-10 01:23:17 +0100 |
|---|---|---|
| committer | mlugg <mlugg@mlugg.co.uk> | 2023-06-25 14:05:18 +0100 |
| commit | 2611d97fb07e5cba5657f508e93f01d60a2379bd (patch) | |
| tree | fb2259414179756f86f79d176283d621a63b3168 /src | |
| parent | 3f04231600e7ec2e16f5fb33f2e81eea24bdc41b (diff) | |
| download | zig-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.zig | 15 |
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).?)); |
