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(...@@ -10216,7 +10216,7 @@ fn llvmFieldIndex(
10216 llvm_field_index += 1;10216 llvm_field_index += 1;
10217 }10217 }
1021810218
10219 if (field_index == i) {10219 if (field_index <= i) {
10220 ptr_pl_buf.* = .{10220 ptr_pl_buf.* = .{
10221 .data = .{10221 .data = .{
10222 .pointee_type = field_ty,10222 .pointee_type = field_ty,
...@@ -10249,7 +10249,7 @@ fn llvmFieldIndex(...@@ -10249,7 +10249,7 @@ fn llvmFieldIndex(
10249 llvm_field_index += 1;10249 llvm_field_index += 1;
10250 }10250 }
1025110251
10252 if (field_index == i) {10252 if (field_index <= i) {
10253 ptr_pl_buf.* = .{10253 ptr_pl_buf.* = .{
10254 .data = .{10254 .data = .{
10255 .pointee_type = field.ty,10255 .pointee_type = field.ty,
test/behavior/struct.zig+20
...@@ -1398,3 +1398,23 @@ test "under-aligned struct field" {...@@ -1398,3 +1398,23 @@ test "under-aligned struct field" {
1398 const result = std.mem.readIntNative(u64, array[4..12]);1398 const result = std.mem.readIntNative(u64, array[4..12]);
1399 try expect(result == 1234);1399 try expect(result == 1234);
1400}1400}
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}