authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-08 19:31:09+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-11 17:59:53+02:00
logd2cc55109a64aaf004384b942e08e95829b9341f
treea58057825963288dc93d51c6295b5879611d8493
parentc4465556fdf14d87f718a7aced5210ec457c1f5a

llvm: correct calculation of index of zero-bit field

If the field comes before any non-zero-bit field then the index of the next field should be returned. Closes #13363

2 files changed, 22 insertions(+), 2 deletions(-)

src/codegen/llvm.zig+2-2
......@@ -10216,7 +10216,7 @@ fn llvmFieldIndex(
1021610216 llvm_field_index += 1;
1021710217 }
1021810218
10219 if (field_index == i) {
10219 if (field_index <= i) {
1022010220 ptr_pl_buf.* = .{
1022110221 .data = .{
1022210222 .pointee_type = field_ty,
......@@ -10249,7 +10249,7 @@ fn llvmFieldIndex(
1024910249 llvm_field_index += 1;
1025010250 }
1025110251
10252 if (field_index == i) {
10252 if (field_index <= i) {
1025310253 ptr_pl_buf.* = .{
1025410254 .data = .{
1025510255 .pointee_type = field.ty,
test/behavior/struct.zig+20
......@@ -1398,3 +1398,23 @@ test "under-aligned struct field" {
13981398 const result = std.mem.readIntNative(u64, array[4..12]);
13991399 try expect(result == 1234);
14001400}
1401
1402test "address of zero-bit field is equal to address of only field" {
1403 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1404 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1405 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1406 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1407
1408 {
1409 const A = struct { b: void = {}, u: u8 };
1410 var a = A{ .u = 0 };
1411 const a_ptr = @fieldParentPtr(A, "b", &a.b);
1412 try std.testing.expectEqual(&a, a_ptr);
1413 }
1414 {
1415 const A = struct { u: u8, b: void = {} };
1416 var a = A{ .u = 0 };
1417 const a_ptr = @fieldParentPtr(A, "b", &a.b);
1418 try std.testing.expectEqual(&a, a_ptr);
1419 }
1420}