diff --git a/src/Air/Legalize.zig b/src/Air/Legalize.zig index 535d9394654a130ef856342f3390473d6664cf93..64fd462b7bd8e041a65c3ec89616db830776349b 100644 --- a/src/Air/Legalize.zig +++ b/src/Air/Legalize.zig @@ -2906,12 +2906,18 @@ fn packedAggregateInitBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro const orig_ty_pl = l.air_instructions.items(.data)[@backingInt(orig_inst)].ty_pl; const agg_ty = orig_ty_pl.ty.toType(); const agg_field_count = agg_ty.structFieldCount(zcu); + var opv_field_count: u32 = 0; + for (0..agg_field_count) |field_idx| { + const field_ty = agg_ty.fieldType(field_idx, zcu); + const field_bits: u16 = @intCast(field_ty.bitSize(zcu)); + if (field_bits == 0) opv_field_count += 1; + } var bfa_buf: [4 * 32 + 2]Air.Inst.Index = undefined; var bfa_state: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), gpa); const bfa = bfa_state.allocator(); - const inst_buf = try bfa.alloc(Air.Inst.Index, 4 * agg_field_count + 2); + const inst_buf = try bfa.alloc(Air.Inst.Index, 4 * (agg_field_count - opv_field_count) + 2); defer bfa.free(inst_buf); var main_block: Block = .init(inst_buf); @@ -2927,6 +2933,7 @@ fn packedAggregateInitBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro field_idx -= 1; const field_ty = agg_ty.fieldType(field_idx, zcu); const field_bits: u16 = @intCast(field_ty.bitSize(zcu)); + if (field_bits == 0) continue; assert(field_bits < num_bits); const field_uint_ty = try pt.intType(.unsigned, field_bits); const field_bit_size_ref: Air.Inst.Ref = .fromValue(try pt.intValue(shift_ty, field_bits)); diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index 785daa0d3194b00d43c00760a11199075d9377dd..d790d68416add0ba62603eaabaa691d1bdfe9c32 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -432,6 +432,22 @@ test "@bitCast of packed struct with void field to integer" { try comptime S.doTheTest(123); } +test "@bitCast of packed struct with void field and multiple integers" { + const S = packed struct { + x: u8, + v: void, + y: u8, + + fn doTheTest(x: u8, y: u8) !void { + const foo = @as(@This(), .{ .x = x, .v = {}, .y = y }); + const as_int: u16 = @bitCast(foo); + try expect(as_int == @as(u16, y) << 8 | x); + } + }; + try S.doTheTest(123, 45); + try comptime S.doTheTest(123, 45); +} + test "@bitCast vector to array with different element size" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;