authorgravatar for stojkovic.igor+git@gmail.comIgor Stojkovic <stojkovic.igor+git@gmail.com> 2022-04-09 12:43:30+02:00
committergravatar for stojkovic.igor+git@gmail.comIgor Stojkovic <stojkovic.igor+git@gmail.com> 2022-04-09 12:43:30+02:00
log19e343b8d46725265eb72796bec506050e182900
treeb13d542355a925d329f8f17a237e48b0a9bde2d2
parent109e730c8ccdfe144f568f232578ab600ef4f33c

stage1: Additional fix for packed structs


2 files changed, 33 insertions(+), 0 deletions(-)

src/stage1/ir.cpp+3
......@@ -15484,6 +15484,9 @@ static Stage1AirInst *ir_analyze_struct_field_ptr(IrAnalyze *ira, Scope *scope,
1548415484 assert(struct_ptr->value->type->id == ZigTypeIdPointer);
1548515485 uint32_t ptr_bit_offset = struct_ptr->value->type->data.pointer.bit_offset_in_host;
1548615486 uint32_t ptr_host_int_bytes = struct_ptr->value->type->data.pointer.host_int_bytes;
15487 if (ptr_host_int_bytes > 0) {
15488 ptr_bit_offset += field->offset * 8;
15489 }
1548715490 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
1548815491 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
1548915492 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
test/behavior/packed-struct.zig+30
......@@ -322,3 +322,33 @@ test "nested packed structs" {
322322 try expectEqual(9, @offsetOf(S6, "c"));
323323 try expectEqual(72, @bitOffsetOf(S6, "c"));
324324}
325
326test "regular in irregular packed struct" {
327 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
328 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
329 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
330 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
331 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
332 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
333 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest;
334 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
335
336 const Irregular = packed struct {
337 bar: Regular = Regular{},
338
339 // This field forces the regular packed struct to be a part of single u48
340 // and thus it all gets represented as an array of 6 bytes in LLVM
341 _: u24 = 0,
342
343 // This struct on its own can represent its fields directly in LLVM
344 // with no need to use array of bytes as underlaying representation.
345 pub const Regular = packed struct { a: u16 = 0, b: u8 = 0 };
346 };
347
348 var foo = Irregular{};
349 foo.bar.a = 235;
350 foo.bar.b = 42;
351
352 try expectEqual(@as(u16, 235), foo.bar.a);
353 try expectEqual(@as(u8, 42), foo.bar.b);
354}