diff options
| author | Xavier Bouchoux <xavierb@gmail.com> | 2023-07-29 20:08:08 +0200 |
|---|---|---|
| committer | Xavier Bouchoux <xavierb@gmail.com> | 2023-10-03 06:39:20 +0200 |
| commit | 62d178e91af57c19d0ac000fe6930039a23e53a3 (patch) | |
| tree | f849674dd8aa13839319e05585b8513a0192b7ba /src/arch/wasm/CodeGen.zig | |
| parent | 412d863ba5801c1376af7ab8f04a71b839a820a6 (diff) | |
| download | zig-62d178e91af57c19d0ac000fe6930039a23e53a3.tar.gz zig-62d178e91af57c19d0ac000fe6930039a23e53a3.zip | |
codegen: fix field offsets in packed structs
* add nested packed struct/union behavior tests
* use ptr_info.packed_offset rather than trying to duplicate the logic from Sema.structFieldPtrByIndex()
* use the container_ptr_info.packed_offset to account for non-aligned nested structs.
* dedup type.packedStructFieldBitOffset() and module.structPackedFieldBitOffset()
Diffstat (limited to 'src/arch/wasm/CodeGen.zig')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 850e08a6bc..1fc28a8287 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -3090,12 +3090,19 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue return func.lowerParentPtr(elem.base.toValue(), @as(u32, @intCast(elem_offset + offset))); }, .field => |field| { - const parent_ty = mod.intern_pool.typeOf(field.base).toType().childType(mod); + const parent_ptr_ty = mod.intern_pool.typeOf(field.base).toType(); + const parent_ty = parent_ptr_ty.childType(mod); + const field_index: u32 = @intCast(field.index); const field_offset = switch (parent_ty.zigTypeTag(mod)) { - .Struct => switch (parent_ty.containerLayout(mod)) { - .Packed => parent_ty.packedStructFieldByteOffset(@as(usize, @intCast(field.index)), mod), - else => parent_ty.structFieldOffset(@as(usize, @intCast(field.index)), mod), + .Struct => blk: { + if (mod.typeToPackedStruct(parent_ty)) |struct_type| { + if (ptr.ty.toType().ptrInfo(mod).packed_offset.host_size == 0) + break :blk @divExact(mod.structPackedFieldBitOffset(struct_type, field_index) + parent_ptr_ty.ptrInfo(mod).packed_offset.bit_offset, 8) + else + break :blk 0; + } + break :blk parent_ty.structFieldOffset(field_index, mod); }, .Union => switch (parent_ty.containerLayout(mod)) { .Packed => 0, |
