mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
Sema: fix alignment of runtime field pointer of underaligned tuple
This commit is contained in:
parent
d4c5396646
commit
95932e98e5
2 changed files with 30 additions and 4 deletions
16
src/Sema.zig
16
src/Sema.zig
|
|
@ -28617,7 +28617,8 @@ fn tupleFieldPtr(
|
||||||
const pt = sema.pt;
|
const pt = sema.pt;
|
||||||
const zcu = pt.zcu;
|
const zcu = pt.zcu;
|
||||||
const tuple_ptr_ty = sema.typeOf(tuple_ptr);
|
const tuple_ptr_ty = sema.typeOf(tuple_ptr);
|
||||||
const tuple_ty = tuple_ptr_ty.childType(zcu);
|
const tuple_ptr_info = tuple_ptr_ty.ptrInfo(zcu);
|
||||||
|
const tuple_ty: Type = .fromInterned(tuple_ptr_info.child);
|
||||||
try tuple_ty.resolveFields(pt);
|
try tuple_ty.resolveFields(pt);
|
||||||
const field_count = tuple_ty.structFieldCount(zcu);
|
const field_count = tuple_ty.structFieldCount(zcu);
|
||||||
|
|
||||||
|
|
@ -28635,9 +28636,16 @@ fn tupleFieldPtr(
|
||||||
const ptr_field_ty = try pt.ptrTypeSema(.{
|
const ptr_field_ty = try pt.ptrTypeSema(.{
|
||||||
.child = field_ty.toIntern(),
|
.child = field_ty.toIntern(),
|
||||||
.flags = .{
|
.flags = .{
|
||||||
.is_const = !tuple_ptr_ty.ptrIsMutable(zcu),
|
.is_const = tuple_ptr_info.flags.is_const,
|
||||||
.is_volatile = tuple_ptr_ty.isVolatilePtr(zcu),
|
.is_volatile = tuple_ptr_info.flags.is_volatile,
|
||||||
.address_space = tuple_ptr_ty.ptrAddressSpace(zcu),
|
.address_space = tuple_ptr_info.flags.address_space,
|
||||||
|
.alignment = a: {
|
||||||
|
if (tuple_ptr_info.flags.alignment == .none) break :a .none;
|
||||||
|
// The tuple pointer isn't naturally aligned, so the field pointer might be underaligned.
|
||||||
|
const tuple_align = tuple_ptr_info.flags.alignment;
|
||||||
|
const field_align = try field_ty.abiAlignmentSema(pt);
|
||||||
|
break :a tuple_align.min(field_align);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -602,3 +602,21 @@ test "empty union in tuple" {
|
||||||
try std.testing.expectEqualStrings("0", info.@"struct".fields[0].name);
|
try std.testing.expectEqualStrings("0", info.@"struct".fields[0].name);
|
||||||
try std.testing.expect(@typeInfo(info.@"struct".fields[0].type) == .@"union");
|
try std.testing.expect(@typeInfo(info.@"struct".fields[0].type) == .@"union");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "field pointer of underaligned tuple" {
|
||||||
|
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||||
|
const S = struct {
|
||||||
|
fn doTheTest() !void {
|
||||||
|
const T = struct { u8, u32 };
|
||||||
|
var val: T align(2) = .{ 1, 2 };
|
||||||
|
|
||||||
|
comptime assert(@TypeOf(&val[0]) == *u8); // `u8` field pointer isn't overaligned
|
||||||
|
comptime assert(@TypeOf(&val[1]) == *align(2) u32); // `u32` field pointer is correctly underaligned
|
||||||
|
|
||||||
|
try expect(val[0] == 1);
|
||||||
|
try expect(val[1] == 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try S.doTheTest();
|
||||||
|
try comptime S.doTheTest();
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue