stage1: Additional fix for packed structs

This commit is contained in:
Igor Stojkovic 2022-04-09 12:43:30 +02:00
parent 109e730c8c
commit 19e343b8d4
2 changed files with 33 additions and 0 deletions

View File

@ -15484,6 +15484,9 @@ static Stage1AirInst *ir_analyze_struct_field_ptr(IrAnalyze *ira, Scope *scope,
assert(struct_ptr->value->type->id == ZigTypeIdPointer);
uint32_t ptr_bit_offset = struct_ptr->value->type->data.pointer.bit_offset_in_host;
uint32_t ptr_host_int_bytes = struct_ptr->value->type->data.pointer.host_int_bytes;
if (ptr_host_int_bytes > 0) {
ptr_bit_offset += field->offset * 8;
}
uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,

View File

@ -322,3 +322,33 @@ test "nested packed structs" {
try expectEqual(9, @offsetOf(S6, "c"));
try expectEqual(72, @bitOffsetOf(S6, "c"));
}
test "regular in irregular packed struct" {
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const Irregular = packed struct {
bar: Regular = Regular{},
// This field forces the regular packed struct to be a part of single u48
// and thus it all gets represented as an array of 6 bytes in LLVM
_: u24 = 0,
// This struct on its own can represent its fields directly in LLVM
// with no need to use array of bytes as underlaying representation.
pub const Regular = packed struct { a: u16 = 0, b: u8 = 0 };
};
var foo = Irregular{};
foo.bar.a = 235;
foo.bar.b = 42;
try expectEqual(@as(u16, 235), foo.bar.a);
try expectEqual(@as(u8, 42), foo.bar.b);
}