mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
llvm: do not offset packed struct field pointers if they have a host size
Closes #14261
This commit is contained in:
parent
06e9b2c4e3
commit
6e067dc050
@ -3370,7 +3370,7 @@ pub const DeclGen = struct {
|
||||
return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));
|
||||
},
|
||||
.field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {
|
||||
return dg.lowerParentPtr(tv.val);
|
||||
return dg.lowerParentPtr(tv.val, tv.ty.ptrInfo().data.bit_offset % 8 == 0);
|
||||
},
|
||||
.null_value, .zero => {
|
||||
const llvm_type = try dg.lowerType(tv.ty);
|
||||
@ -3378,7 +3378,7 @@ pub const DeclGen = struct {
|
||||
},
|
||||
.opt_payload => {
|
||||
const payload = tv.val.castTag(.opt_payload).?.data;
|
||||
return dg.lowerParentPtr(payload);
|
||||
return dg.lowerParentPtr(payload, tv.ty.ptrInfo().data.bit_offset % 8 == 0);
|
||||
},
|
||||
else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{
|
||||
tv.ty.fmtDebug(), tag,
|
||||
@ -3967,7 +3967,7 @@ pub const DeclGen = struct {
|
||||
return try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index);
|
||||
}
|
||||
|
||||
fn lowerParentPtr(dg: *DeclGen, ptr_val: Value) Error!*llvm.Value {
|
||||
fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
|
||||
const target = dg.module.getTarget();
|
||||
switch (ptr_val.tag()) {
|
||||
.decl_ref_mut => {
|
||||
@ -3996,7 +3996,7 @@ pub const DeclGen = struct {
|
||||
},
|
||||
.field_ptr => {
|
||||
const field_ptr = ptr_val.castTag(.field_ptr).?.data;
|
||||
const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr);
|
||||
const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr, byte_aligned);
|
||||
const parent_ty = field_ptr.container_ty;
|
||||
|
||||
const field_index = @intCast(u32, field_ptr.field_index);
|
||||
@ -4026,6 +4026,7 @@ pub const DeclGen = struct {
|
||||
},
|
||||
.Struct => {
|
||||
if (parent_ty.containerLayout() == .Packed) {
|
||||
if (!byte_aligned) return parent_llvm_ptr;
|
||||
const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth());
|
||||
const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
|
||||
// count bits of fields before this one
|
||||
@ -4072,7 +4073,7 @@ pub const DeclGen = struct {
|
||||
},
|
||||
.elem_ptr => {
|
||||
const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
|
||||
const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr);
|
||||
const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, true);
|
||||
|
||||
const llvm_usize = try dg.lowerType(Type.usize);
|
||||
const indices: [1]*llvm.Value = .{
|
||||
@ -4083,7 +4084,7 @@ pub const DeclGen = struct {
|
||||
},
|
||||
.opt_payload_ptr => {
|
||||
const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
|
||||
const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr);
|
||||
const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr, true);
|
||||
var buf: Type.Payload.ElemType = undefined;
|
||||
|
||||
const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);
|
||||
@ -4105,7 +4106,7 @@ pub const DeclGen = struct {
|
||||
},
|
||||
.eu_payload_ptr => {
|
||||
const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
|
||||
const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr);
|
||||
const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, true);
|
||||
|
||||
const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
|
||||
|
||||
@ -599,3 +599,29 @@ test "packed struct initialized in bitcast" {
|
||||
const t = @bitCast(u8, T{ .val = val });
|
||||
try expect(t == val);
|
||||
}
|
||||
|
||||
test "pointer to container level packed struct field" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) 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_x86_64) return error.SkipZigTest;
|
||||
|
||||
const S = packed struct(u32) {
|
||||
test_bit: bool,
|
||||
someother_data: u12,
|
||||
other_test_bit: bool,
|
||||
someother_more_different_data: u12,
|
||||
other_bits: packed struct(u6) {
|
||||
enable_1: bool,
|
||||
enable_2: bool,
|
||||
enable_3: bool,
|
||||
enable_4: bool,
|
||||
enable_5: bool,
|
||||
enable_6: bool,
|
||||
},
|
||||
var arr = [_]u32{0} ** 2;
|
||||
};
|
||||
@ptrCast(*S, &S.arr[0]).other_bits.enable_3 = true;
|
||||
try expect(S.arr[0] == 0x10000000);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user