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 {...@@ -3789,10 +3789,7 @@ pub const DeclGen = struct {
37893789
3790 fn lowerIntAsPtr(dg: *DeclGen, val: Value) Error!*llvm.Value {3790 fn lowerIntAsPtr(dg: *DeclGen, val: Value) Error!*llvm.Value {
3791 switch (dg.module.intern_pool.indexToKey(val.toIntern())) {3791 switch (dg.module.intern_pool.indexToKey(val.toIntern())) {
3792 .undef => {3792 .undef => return dg.context.pointerType(0).getUndef(),
3793 const llvm_usize = try dg.lowerType(Type.usize);
3794 return llvm_usize.getUndef();
3795 },
3796 .int => {3793 .int => {
3797 var bigint_space: Value.BigIntSpace = undefined;3794 var bigint_space: Value.BigIntSpace = undefined;
3798 const bigint = val.toBigInt(&bigint_space, dg.module);3795 const bigint = val.toBigInt(&bigint_space, dg.module);
...@@ -3847,141 +3844,137 @@ pub const DeclGen = struct {...@@ -3847,141 +3844,137 @@ pub const DeclGen = struct {
3847 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {3844 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
3848 const mod = dg.module;3845 const mod = dg.module;
3849 const target = mod.getTarget();3846 const target = mod.getTarget();
3850 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {3847 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
3851 .int => dg.lowerIntAsPtr(ptr_val),3848 .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),
3852 .ptr => |ptr| switch (ptr.addr) {3849 .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),
3853 .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),3850 .int => |int| dg.lowerIntAsPtr(int.toValue()),
3854 .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),3851 .eu_payload => |eu_ptr| {
3855 .int => |int| dg.lowerIntAsPtr(int.toValue()),3852 const parent_llvm_ptr = try dg.lowerParentPtr(eu_ptr.toValue(), true);
3856 .eu_payload => |eu_ptr| {3853
3857 const parent_llvm_ptr = try dg.lowerParentPtr(eu_ptr.toValue(), true);3854 const eu_ty = mod.intern_pool.typeOf(eu_ptr).toType().childType(mod);
38583855 const payload_ty = eu_ty.errorUnionPayload(mod);
3859 const eu_ty = mod.intern_pool.typeOf(eu_ptr).toType().childType(mod);3856 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3860 const payload_ty = eu_ty.errorUnionPayload(mod);3857 // In this case, we represent pointer to error union the same as pointer
3861 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {3858 // to the payload.
3862 // In this case, we represent pointer to error union the same as pointer3859 return parent_llvm_ptr;
3863 // to the payload.3860 }
3864 return parent_llvm_ptr;
3865 }
38663861
3867 const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;3862 const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;
3868 const llvm_u32 = dg.context.intType(32);3863 const llvm_u32 = dg.context.intType(32);
3869 const indices: [2]*llvm.Value = .{3864 const indices: [2]*llvm.Value = .{
3870 llvm_u32.constInt(0, .False),3865 llvm_u32.constInt(0, .False),
3871 llvm_u32.constInt(payload_offset, .False),3866 llvm_u32.constInt(payload_offset, .False),
3872 };3867 };
3873 const eu_llvm_ty = try dg.lowerType(eu_ty);3868 const eu_llvm_ty = try dg.lowerType(eu_ty);
3874 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);3869 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3875 },3870 },
3876 .opt_payload => |opt_ptr| {3871 .opt_payload => |opt_ptr| {
3877 const parent_llvm_ptr = try dg.lowerParentPtr(opt_ptr.toValue(), true);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);3874 const opt_ty = mod.intern_pool.typeOf(opt_ptr).toType().childType(mod);
3880 const payload_ty = opt_ty.optionalChild(mod);3875 const payload_ty = opt_ty.optionalChild(mod);
3881 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or3876 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or
3882 payload_ty.optionalReprIsPayload(mod))3877 payload_ty.optionalReprIsPayload(mod))
3883 {3878 {
3884 // In this case, we represent pointer to optional the same as pointer3879 // In this case, we represent pointer to optional the same as pointer
3885 // to the payload.3880 // to the payload.
3886 return parent_llvm_ptr;3881 return parent_llvm_ptr;
3887 }3882 }
38883883
3889 const llvm_u32 = dg.context.intType(32);3884 const llvm_u32 = dg.context.intType(32);
3890 const indices: [2]*llvm.Value = .{3885 const indices: [2]*llvm.Value = .{
3891 llvm_u32.constInt(0, .False),3886 llvm_u32.constInt(0, .False),
3892 llvm_u32.constInt(0, .False),3887 llvm_u32.constInt(0, .False),
3893 };3888 };
3894 const opt_llvm_ty = try dg.lowerType(opt_ty);3889 const opt_llvm_ty = try dg.lowerType(opt_ty);
3895 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);3890 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3896 },3891 },
3897 .comptime_field => unreachable,3892 .comptime_field => unreachable,
3898 .elem => |elem_ptr| {3893 .elem => |elem_ptr| {
3899 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.base.toValue(), true);3894 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.base.toValue(), true);
39003895
3901 const llvm_usize = try dg.lowerType(Type.usize);3896 const llvm_usize = try dg.lowerType(Type.usize);
3902 const indices: [1]*llvm.Value = .{3897 const indices: [1]*llvm.Value = .{
3903 llvm_usize.constInt(elem_ptr.index, .False),3898 llvm_usize.constInt(elem_ptr.index, .False),
3904 };3899 };
3905 const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);3900 const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);
3906 const elem_llvm_ty = try dg.lowerType(elem_ty);3901 const elem_llvm_ty = try dg.lowerType(elem_ty);
3907 return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);3902 return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3908 },3903 },
3909 .field => |field_ptr| {3904 .field => |field_ptr| {
3910 const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.base.toValue(), byte_aligned);3905 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);3906 const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
39123907
3913 const field_index = @intCast(u32, field_ptr.index);3908 const field_index = @intCast(u32, field_ptr.index);
3914 const llvm_u32 = dg.context.intType(32);3909 const llvm_u32 = dg.context.intType(32);
3915 switch (parent_ty.zigTypeTag(mod)) {3910 switch (parent_ty.zigTypeTag(mod)) {
3916 .Union => {3911 .Union => {
3917 if (parent_ty.containerLayout(mod) == .Packed) {3912 if (parent_ty.containerLayout(mod) == .Packed) {
3918 return parent_llvm_ptr;3913 return parent_llvm_ptr;
3919 }3914 }
39203915
3921 const layout = parent_ty.unionGetLayout(mod);3916 const layout = parent_ty.unionGetLayout(mod);
3922 if (layout.payload_size == 0) {3917 if (layout.payload_size == 0) {
3923 // In this case a pointer to the union and a pointer to any3918 // In this case a pointer to the union and a pointer to any
3924 // (void) payload is the same.3919 // (void) payload is the same.
3925 return parent_llvm_ptr;3920 return parent_llvm_ptr;
3926 }3921 }
3927 const llvm_pl_index = if (layout.tag_size == 0)3922 const llvm_pl_index = if (layout.tag_size == 0)
3928 03923 0
3929 else3924 else
3930 @boolToInt(layout.tag_align >= layout.payload_align);3925 @boolToInt(layout.tag_align >= layout.payload_align);
3931 const indices: [2]*llvm.Value = .{3926 const indices: [2]*llvm.Value = .{
3932 llvm_u32.constInt(0, .False),3927 llvm_u32.constInt(0, .False),
3933 llvm_u32.constInt(llvm_pl_index, .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;
3934 };3946 };
3935 const parent_llvm_ty = try dg.lowerType(parent_ty);3947 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
3936 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);3948 const field_addr = base_addr.constAdd(byte_offset);
3937 },3949 const final_llvm_ty = dg.context.pointerType(0);
3938 .Struct => {3950 return field_addr.constIntToPtr(final_llvm_ty);
3939 if (parent_ty.containerLayout(mod) == .Packed) {3951 }
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 }
39573952
3958 const parent_llvm_ty = try dg.lowerType(parent_ty);3953 const parent_llvm_ty = try dg.lowerType(parent_ty);
3959 if (llvmField(parent_ty, field_index, mod)) |llvm_field| {3954 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));
3973 const indices: [2]*llvm.Value = .{3955 const indices: [2]*llvm.Value = .{
3974 llvm_u32.constInt(0, .False),3956 llvm_u32.constInt(0, .False),
3975 llvm_u32.constInt(field_index, .False),3957 llvm_u32.constInt(llvm_field.index, .False),
3976 };3958 };
3977 const parent_llvm_ty = try dg.lowerType(parent_ty);
3978 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);3959 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3979 },3960 } else {
3980 else => unreachable,3961 const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);
3981 }3962 const indices: [1]*llvm.Value = .{llvm_index};
3982 },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 }
3983 },3977 },
3984 else => unreachable,
3985 };3978 };
3986 }3979 }
39873980