diff --git a/src/codegen/spirv/CodeGen.zig b/src/codegen/spirv/CodeGen.zig index 7c2595beec3d7322284ac8b111d9c71e0be53911..fa304a7473a5b0777702830faf79293bc8a05a4f 100644 --- a/src/codegen/spirv/CodeGen.zig +++ b/src/codegen/spirv/CodeGen.zig @@ -6732,7 +6732,7 @@ fn airAggFieldVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id { if (field_ty.isInt(zcu)) return result_id; return try cg.bitCast(field_ty, field_int_ty, result_id); }, - else => return try cg.extractField(field_ty, object_id, field_index), + else => return try cg.extractField(field_ty, object_id, cg.memberIndex(object_ty, field_index)), }, .@"union" => switch (object_ty.containerLayout(zcu)) { .@"packed" => { @@ -6882,7 +6882,8 @@ fn structFieldPtr( return result_id; }, .auto, .@"extern" => { - return try cg.accessChain(result_ty_id, object_ptr, &.{field_index}); + const member_index = cg.memberIndex(object_ty, field_index); + return try cg.accessChain(result_ty_id, object_ptr, &.{member_index}); }, }, .@"union" => switch (object_ty.containerLayout(zcu)) { @@ -6937,6 +6938,33 @@ fn structFieldPtr( } } +fn memberIndex(cg: *CodeGen, struct_ty: Type, field_index: u32) u32 { + const zcu = cg.zcu; + const ip = &zcu.intern_pool; + var index: u32 = 0; + switch (ip.indexToKey(struct_ty.toIntern())) { + .tuple_type => |tuple| { + const types = tuple.types.get(ip)[0..field_index]; + for (types, tuple.values.get(ip)[0..field_index]) |field_ty_index, field_val| { + const field_ty: Type = .fromInterned(field_ty_index); + if (field_val != .none or !field_ty.hasRuntimeBits(zcu)) continue; + index += 1; + } + }, + .struct_type => { + const struct_type = ip.loadStructType(struct_ty.toIntern()); + var it = struct_type.iterateRuntimeOrder(ip); + while (it.next()) |i| { + if (i == field_index) break; + const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]); + if (field_ty.hasRuntimeBits(zcu)) index += 1; + } + }, + else => unreachable, + } + return index; +} + fn airStructFieldPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id { const ty_pl = cg.air.instructions.items(.data)[@backingInt(inst)].ty_pl; const struct_field = cg.air.extraData(Air.StructField, ty_pl.payload).data; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 00a42d3b384540b891f4962a3add671b453064da..b65833a251ae69f60cdef52c7e0f9eacc0e89e8d 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -1945,8 +1945,6 @@ test "struct field default value is a call" { } test "aggregate initializers should allow initializing comptime fields, verifying equality" { - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - var x: u32 = 15; _ = &x; const T = @TypeOf(.{ @as(i32, -1234), @as(u32, 5678), x }); diff --git a/test/behavior/tuple.zig b/test/behavior/tuple.zig index 6be6c65fb51292a7982337dab704dadb6b4336e4..2241de5dcb8d12bab80303496a2b83e0c2e7f376 100644 --- a/test/behavior/tuple.zig +++ b/test/behavior/tuple.zig @@ -203,8 +203,6 @@ test "offsetOf anon struct" { } test "initializing tuple with mixed comptime-runtime fields" { - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - var x: u32 = 15; _ = &x; const T = @TypeOf(.{ @as(i32, -1234), @as(u32, 5678), x });