Skip to content

Commit 95932e9

Browse files
committed
Sema: fix alignment of runtime field pointer of underaligned tuple
1 parent d4c5396 commit 95932e9

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

src/Sema.zig

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28617,7 +28617,8 @@ fn tupleFieldPtr(
2861728617
const pt = sema.pt;
2861828618
const zcu = pt.zcu;
2861928619
const tuple_ptr_ty = sema.typeOf(tuple_ptr);
28620-
const tuple_ty = tuple_ptr_ty.childType(zcu);
28620+
const tuple_ptr_info = tuple_ptr_ty.ptrInfo(zcu);
28621+
const tuple_ty: Type = .fromInterned(tuple_ptr_info.child);
2862128622
try tuple_ty.resolveFields(pt);
2862228623
const field_count = tuple_ty.structFieldCount(zcu);
2862328624

@@ -28635,9 +28636,16 @@ fn tupleFieldPtr(
2863528636
const ptr_field_ty = try pt.ptrTypeSema(.{
2863628637
.child = field_ty.toIntern(),
2863728638
.flags = .{
28638-
.is_const = !tuple_ptr_ty.ptrIsMutable(zcu),
28639-
.is_volatile = tuple_ptr_ty.isVolatilePtr(zcu),
28640-
.address_space = tuple_ptr_ty.ptrAddressSpace(zcu),
28639+
.is_const = tuple_ptr_info.flags.is_const,
28640+
.is_volatile = tuple_ptr_info.flags.is_volatile,
28641+
.address_space = tuple_ptr_info.flags.address_space,
28642+
.alignment = a: {
28643+
if (tuple_ptr_info.flags.alignment == .none) break :a .none;
28644+
// The tuple pointer isn't naturally aligned, so the field pointer might be underaligned.
28645+
const tuple_align = tuple_ptr_info.flags.alignment;
28646+
const field_align = try field_ty.abiAlignmentSema(pt);
28647+
break :a tuple_align.min(field_align);
28648+
},
2864128649
},
2864228650
});
2864328651

test/behavior/tuple.zig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,3 +602,21 @@ test "empty union in tuple" {
602602
try std.testing.expectEqualStrings("0", info.@"struct".fields[0].name);
603603
try std.testing.expect(@typeInfo(info.@"struct".fields[0].type) == .@"union");
604604
}
605+
606+
test "field pointer of underaligned tuple" {
607+
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
608+
const S = struct {
609+
fn doTheTest() !void {
610+
const T = struct { u8, u32 };
611+
var val: T align(2) = .{ 1, 2 };
612+
613+
comptime assert(@TypeOf(&val[0]) == *u8); // `u8` field pointer isn't overaligned
614+
comptime assert(@TypeOf(&val[1]) == *align(2) u32); // `u32` field pointer is correctly underaligned
615+
616+
try expect(val[0] == 1);
617+
try expect(val[1] == 2);
618+
}
619+
};
620+
try S.doTheTest();
621+
try comptime S.doTheTest();
622+
}

0 commit comments

Comments
 (0)