@@ -4258,6 +4258,72 @@ fn validateStructInit(
4258
4258
}
4259
4259
try sema.resolveStructLayout(struct_ty);
4260
4260
4261
+ if (struct_ty.containerLayout() == .Packed) {
4262
+ // Convert stores to ptr into an aggregate init.
4263
+ const element_refs = try sema.arena.alloc(Air.Inst.Ref, struct_ty.structFieldCount());
4264
+
4265
+ var block_index = block.instructions.items.len - 1;
4266
+ var field_ptr_count = instrs.len;
4267
+ while (block_index > 0 and field_ptr_count > 0) : (block_index -= 1) {
4268
+ const store_inst = block.instructions.items[block_index];
4269
+ if (air_tags[store_inst] != .store) continue;
4270
+ const store_index = block_index;
4271
+ const bin_op = air_datas[store_inst].bin_op;
4272
+ var lhs_index = Air.refToIndex(bin_op.lhs) orelse continue;
4273
+ var bitcast_index: ?usize = null;
4274
+ {
4275
+ if (air_tags[lhs_index] == .bitcast) {
4276
+ const lhs = air_datas[lhs_index].ty_op.operand;
4277
+ lhs_index = Air.refToIndex(lhs).?;
4278
+ while (block_index > 0) : (block_index -= 1) {
4279
+ if (block.instructions.items[block_index] == lhs_index) {
4280
+ bitcast_index = block_index;
4281
+ break;
4282
+ }
4283
+ } else continue;
4284
+ }
4285
+ }
4286
+ const index = switch (air_tags[lhs_index]) {
4287
+ .struct_field_ptr_index_0 => 0,
4288
+ .struct_field_ptr_index_1 => 1,
4289
+ .struct_field_ptr_index_2 => 2,
4290
+ .struct_field_ptr_index_3 => 3,
4291
+ .struct_field_ptr => blk: {
4292
+ const ty_pl = air_datas[lhs_index].ty_pl;
4293
+ const struct_field = sema.getTmpAir().extraData(Air.StructField, ty_pl.payload).data;
4294
+ break :blk struct_field.field_index;
4295
+ },
4296
+ else => continue,
4297
+ };
4298
+ _ = block.instructions.orderedRemove(store_index);
4299
+ block_index -= 1;
4300
+ if (bitcast_index) |some| {
4301
+ _ = block.instructions.orderedRemove(some);
4302
+ block_index -= 1;
4303
+ }
4304
+ while (block_index > 0) : (block_index -= 1) {
4305
+ if (block.instructions.items[block_index] == lhs_index) {
4306
+ _ = block.instructions.orderedRemove(block_index);
4307
+ block_index -= 1;
4308
+ break;
4309
+ }
4310
+ }
4311
+ field_ptr_count -= 1;
4312
+ element_refs[index] = bin_op.rhs;
4313
+ continue;
4314
+ }
4315
+
4316
+ for (found_fields) |field_ptr, i| {
4317
+ if (field_ptr != 0) continue;
4318
+
4319
+ element_refs[i] = try sema.addConstant(struct_ty.structFieldType(i), field_values[i]);
4320
+ }
4321
+
4322
+ const init = try block.addAggregateInit(struct_ty, element_refs);
4323
+ try sema.storePtr2(block, init_src, struct_ptr, init_src, init, init_src, .store);
4324
+ return;
4325
+ }
4326
+
4261
4327
// Our task is to insert `store` instructions for all the default field values.
4262
4328
for (found_fields) |field_ptr, i| {
4263
4329
if (field_ptr != 0) continue;
0 commit comments