mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
LLVM: fix lowering byte-aligned packed struct field pointers
This commit is contained in:
parent
dfc7493dcb
commit
f880af369d
@ -3646,6 +3646,24 @@ pub const DeclGen = struct {
|
||||
},
|
||||
.Struct => {
|
||||
const field_ty = parent_ty.structFieldType(field_index);
|
||||
if (parent_ty.containerLayout() == .Packed) {
|
||||
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
|
||||
const prev_bits = b: {
|
||||
var b: usize = 0;
|
||||
for (parent_ty.structFields().values()[0..field_index]) |field| {
|
||||
if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime()) continue;
|
||||
b += field.ty.bitSize(target);
|
||||
}
|
||||
break :b b;
|
||||
};
|
||||
const byte_offset = llvm_usize.constInt((prev_bits + 7) / 8, .False);
|
||||
const field_addr = base_addr.constAdd(byte_offset);
|
||||
bitcast_needed = false;
|
||||
const final_llvm_ty = (try dg.lowerType(ptr_child_ty)).pointerType(0);
|
||||
break :blk field_addr.constIntToPtr(final_llvm_ty);
|
||||
}
|
||||
bitcast_needed = !field_ty.eql(ptr_child_ty, dg.module);
|
||||
|
||||
var ty_buf: Type.Payload.Pointer = undefined;
|
||||
|
||||
@ -169,6 +169,9 @@ pub const Value = opaque {
|
||||
pub const constNot = LLVMConstNot;
|
||||
extern fn LLVMConstNot(ConstantVal: *const Value) *const Value;
|
||||
|
||||
pub const constAdd = LLVMConstAdd;
|
||||
extern fn LLVMConstAdd(LHSConstant: *const Value, RHSConstant: *const Value) *const Value;
|
||||
|
||||
pub const setWeak = LLVMSetWeak;
|
||||
extern fn LLVMSetWeak(CmpXchgInst: *const Value, IsWeak: Bool) void;
|
||||
|
||||
|
||||
@ -436,3 +436,25 @@ test "load pointer from packed struct" {
|
||||
try expect(i == 123);
|
||||
}
|
||||
}
|
||||
|
||||
test "@ptrToInt on a packed struct field" {
|
||||
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;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
const P = packed struct {
|
||||
x: u8,
|
||||
y: u8,
|
||||
z: u32,
|
||||
};
|
||||
var p0: P = P{
|
||||
.x = 1,
|
||||
.y = 2,
|
||||
.z = 0,
|
||||
};
|
||||
};
|
||||
try expect(@ptrToInt(&S.p0.z) - @ptrToInt(&S.p0.x) == 2);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user