Skip to content

Commit d2cc551

Browse files
committed
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
1 parent c446555 commit d2cc551

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

src/codegen/llvm.zig

+2-2
Original file line numberDiff line numberDiff line change
@@ -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
Original file line numberDiff line numberDiff line change
@@ -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+
1402+
test "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+
}

0 commit comments

Comments
 (0)