authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-06-01 22:05:54-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:59-07:00
logbc3b56f957d950edb6fde3585f8e9f4dda009d3e
treea1757c0438d0d5a613f36fac9600bfe9cf3e3cbb
parent35550c840b07df017b360c81c3cd0a8a3da55aae

llvm: fix undefined pointer type


1 files changed, 120 insertions(+), 127 deletions(-)

src/codegen/llvm.zig+120-127
......@@ -3789,10 +3789,7 @@ pub const DeclGen = struct {
37893789
37903790 fn lowerIntAsPtr(dg: *DeclGen, val: Value) Error!*llvm.Value {
37913791 switch (dg.module.intern_pool.indexToKey(val.toIntern())) {
3792 .undef => {
3793 const llvm_usize = try dg.lowerType(Type.usize);
3794 return llvm_usize.getUndef();
3795 },
3792 .undef => return dg.context.pointerType(0).getUndef(),
37963793 .int => {
37973794 var bigint_space: Value.BigIntSpace = undefined;
37983795 const bigint = val.toBigInt(&bigint_space, dg.module);
......@@ -3847,141 +3844,137 @@ pub const DeclGen = struct {
38473844 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
38483845 const mod = dg.module;
38493846 const target = mod.getTarget();
3850 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {
3851 .int => dg.lowerIntAsPtr(ptr_val),
3852 .ptr => |ptr| switch (ptr.addr) {
3853 .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),
3854 .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),
3855 .int => |int| dg.lowerIntAsPtr(int.toValue()),
3856 .eu_payload => |eu_ptr| {
3857 const parent_llvm_ptr = try dg.lowerParentPtr(eu_ptr.toValue(), true);
3858
3859 const eu_ty = mod.intern_pool.typeOf(eu_ptr).toType().childType(mod);
3860 const payload_ty = eu_ty.errorUnionPayload(mod);
3861 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3862 // In this case, we represent pointer to error union the same as pointer
3863 // to the payload.
3864 return parent_llvm_ptr;
3865 }
3847 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
3848 .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),
3849 .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),
3850 .int => |int| dg.lowerIntAsPtr(int.toValue()),
3851 .eu_payload => |eu_ptr| {
3852 const parent_llvm_ptr = try dg.lowerParentPtr(eu_ptr.toValue(), true);
3853
3854 const eu_ty = mod.intern_pool.typeOf(eu_ptr).toType().childType(mod);
3855 const payload_ty = eu_ty.errorUnionPayload(mod);
3856 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3857 // In this case, we represent pointer to error union the same as pointer
3858 // to the payload.
3859 return parent_llvm_ptr;
3860 }
38663861
3867 const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;
3868 const llvm_u32 = dg.context.intType(32);
3869 const indices: [2]*llvm.Value = .{
3870 llvm_u32.constInt(0, .False),
3871 llvm_u32.constInt(payload_offset, .False),
3872 };
3873 const eu_llvm_ty = try dg.lowerType(eu_ty);
3874 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3875 },
3876 .opt_payload => |opt_ptr| {
3877 const parent_llvm_ptr = try dg.lowerParentPtr(opt_ptr.toValue(), true);
3862 const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;
3863 const llvm_u32 = dg.context.intType(32);
3864 const indices: [2]*llvm.Value = .{
3865 llvm_u32.constInt(0, .False),
3866 llvm_u32.constInt(payload_offset, .False),
3867 };
3868 const eu_llvm_ty = try dg.lowerType(eu_ty);
3869 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3870 },
3871 .opt_payload => |opt_ptr| {
3872 const parent_llvm_ptr = try dg.lowerParentPtr(opt_ptr.toValue(), true);
38783873
3879 const opt_ty = mod.intern_pool.typeOf(opt_ptr).toType().childType(mod);
3880 const payload_ty = opt_ty.optionalChild(mod);
3881 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or
3882 payload_ty.optionalReprIsPayload(mod))
3883 {
3884 // In this case, we represent pointer to optional the same as pointer
3885 // to the payload.
3886 return parent_llvm_ptr;
3887 }
3874 const opt_ty = mod.intern_pool.typeOf(opt_ptr).toType().childType(mod);
3875 const payload_ty = opt_ty.optionalChild(mod);
3876 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or
3877 payload_ty.optionalReprIsPayload(mod))
3878 {
3879 // In this case, we represent pointer to optional the same as pointer
3880 // to the payload.
3881 return parent_llvm_ptr;
3882 }
38883883
3889 const llvm_u32 = dg.context.intType(32);
3890 const indices: [2]*llvm.Value = .{
3891 llvm_u32.constInt(0, .False),
3892 llvm_u32.constInt(0, .False),
3893 };
3894 const opt_llvm_ty = try dg.lowerType(opt_ty);
3895 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3896 },
3897 .comptime_field => unreachable,
3898 .elem => |elem_ptr| {
3899 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.base.toValue(), true);
3884 const llvm_u32 = dg.context.intType(32);
3885 const indices: [2]*llvm.Value = .{
3886 llvm_u32.constInt(0, .False),
3887 llvm_u32.constInt(0, .False),
3888 };
3889 const opt_llvm_ty = try dg.lowerType(opt_ty);
3890 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3891 },
3892 .comptime_field => unreachable,
3893 .elem => |elem_ptr| {
3894 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.base.toValue(), true);
39003895
3901 const llvm_usize = try dg.lowerType(Type.usize);
3902 const indices: [1]*llvm.Value = .{
3903 llvm_usize.constInt(elem_ptr.index, .False),
3904 };
3905 const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);
3906 const elem_llvm_ty = try dg.lowerType(elem_ty);
3907 return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3908 },
3909 .field => |field_ptr| {
3910 const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.base.toValue(), byte_aligned);
3911 const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
3912
3913 const field_index = @intCast(u32, field_ptr.index);
3914 const llvm_u32 = dg.context.intType(32);
3915 switch (parent_ty.zigTypeTag(mod)) {
3916 .Union => {
3917 if (parent_ty.containerLayout(mod) == .Packed) {
3918 return parent_llvm_ptr;
3919 }
3896 const llvm_usize = try dg.lowerType(Type.usize);
3897 const indices: [1]*llvm.Value = .{
3898 llvm_usize.constInt(elem_ptr.index, .False),
3899 };
3900 const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);
3901 const elem_llvm_ty = try dg.lowerType(elem_ty);
3902 return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3903 },
3904 .field => |field_ptr| {
3905 const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.base.toValue(), byte_aligned);
3906 const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
3907
3908 const field_index = @intCast(u32, field_ptr.index);
3909 const llvm_u32 = dg.context.intType(32);
3910 switch (parent_ty.zigTypeTag(mod)) {
3911 .Union => {
3912 if (parent_ty.containerLayout(mod) == .Packed) {
3913 return parent_llvm_ptr;
3914 }
39203915
3921 const layout = parent_ty.unionGetLayout(mod);
3922 if (layout.payload_size == 0) {
3923 // In this case a pointer to the union and a pointer to any
3924 // (void) payload is the same.
3925 return parent_llvm_ptr;
3926 }
3927 const llvm_pl_index = if (layout.tag_size == 0)
3928 0
3929 else
3930 @boolToInt(layout.tag_align >= layout.payload_align);
3931 const indices: [2]*llvm.Value = .{
3932 llvm_u32.constInt(0, .False),
3933 llvm_u32.constInt(llvm_pl_index, .False),
3916 const layout = parent_ty.unionGetLayout(mod);
3917 if (layout.payload_size == 0) {
3918 // In this case a pointer to the union and a pointer to any
3919 // (void) payload is the same.
3920 return parent_llvm_ptr;
3921 }
3922 const llvm_pl_index = if (layout.tag_size == 0)
3923 0
3924 else
3925 @boolToInt(layout.tag_align >= layout.payload_align);
3926 const indices: [2]*llvm.Value = .{
3927 llvm_u32.constInt(0, .False),
3928 llvm_u32.constInt(llvm_pl_index, .False),
3929 };
3930 const parent_llvm_ty = try dg.lowerType(parent_ty);
3931 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3932 },
3933 .Struct => {
3934 if (parent_ty.containerLayout(mod) == .Packed) {
3935 if (!byte_aligned) return parent_llvm_ptr;
3936 const llvm_usize = dg.context.intType(target.ptrBitWidth());
3937 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
3938 // count bits of fields before this one
3939 const prev_bits = b: {
3940 var b: usize = 0;
3941 for (parent_ty.structFields(mod).values()[0..field_index]) |field| {
3942 if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
3943 b += @intCast(usize, field.ty.bitSize(mod));
3944 }
3945 break :b b;
39343946 };
3935 const parent_llvm_ty = try dg.lowerType(parent_ty);
3936 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3937 },
3938 .Struct => {
3939 if (parent_ty.containerLayout(mod) == .Packed) {
3940 if (!byte_aligned) return parent_llvm_ptr;
3941 const llvm_usize = dg.context.intType(target.ptrBitWidth());
3942 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
3943 // count bits of fields before this one
3944 const prev_bits = b: {
3945 var b: usize = 0;
3946 for (parent_ty.structFields(mod).values()[0..field_index]) |field| {
3947 if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
3948 b += @intCast(usize, field.ty.bitSize(mod));
3949 }
3950 break :b b;
3951 };
3952 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
3953 const field_addr = base_addr.constAdd(byte_offset);
3954 const final_llvm_ty = dg.context.pointerType(0);
3955 return field_addr.constIntToPtr(final_llvm_ty);
3956 }
3947 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
3948 const field_addr = base_addr.constAdd(byte_offset);
3949 const final_llvm_ty = dg.context.pointerType(0);
3950 return field_addr.constIntToPtr(final_llvm_ty);
3951 }
39573952
3958 const parent_llvm_ty = try dg.lowerType(parent_ty);
3959 if (llvmField(parent_ty, field_index, mod)) |llvm_field| {
3960 const indices: [2]*llvm.Value = .{
3961 llvm_u32.constInt(0, .False),
3962 llvm_u32.constInt(llvm_field.index, .False),
3963 };
3964 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3965 } else {
3966 const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);
3967 const indices: [1]*llvm.Value = .{llvm_index};
3968 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3969 }
3970 },
3971 .Pointer => {
3972 assert(parent_ty.isSlice(mod));
3953 const parent_llvm_ty = try dg.lowerType(parent_ty);
3954 if (llvmField(parent_ty, field_index, mod)) |llvm_field| {
39733955 const indices: [2]*llvm.Value = .{
39743956 llvm_u32.constInt(0, .False),
3975 llvm_u32.constInt(field_index, .False),
3957 llvm_u32.constInt(llvm_field.index, .False),
39763958 };
3977 const parent_llvm_ty = try dg.lowerType(parent_ty);
39783959 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3979 },
3980 else => unreachable,
3981 }
3982 },
3960 } else {
3961 const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);
3962 const indices: [1]*llvm.Value = .{llvm_index};
3963 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3964 }
3965 },
3966 .Pointer => {
3967 assert(parent_ty.isSlice(mod));
3968 const indices: [2]*llvm.Value = .{
3969 llvm_u32.constInt(0, .False),
3970 llvm_u32.constInt(field_index, .False),
3971 };
3972 const parent_llvm_ty = try dg.lowerType(parent_ty);
3973 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3974 },
3975 else => unreachable,
3976 }
39833977 },
3984 else => unreachable,
39853978 };
39863979 }
39873980