Commit bc3b56f957

Jacob Young <jacobly0@users.noreply.github.com>
2023-06-02 04:05:54
llvm: fix undefined pointer type
1 parent 35550c8
Changed files (1)
src
codegen
src/codegen/llvm.zig
@@ -3789,10 +3789,7 @@ pub const DeclGen = struct {
 
     fn lowerIntAsPtr(dg: *DeclGen, val: Value) Error!*llvm.Value {
         switch (dg.module.intern_pool.indexToKey(val.toIntern())) {
-            .undef => {
-                const llvm_usize = try dg.lowerType(Type.usize);
-                return llvm_usize.getUndef();
-            },
+            .undef => return dg.context.pointerType(0).getUndef(),
             .int => {
                 var bigint_space: Value.BigIntSpace = undefined;
                 const bigint = val.toBigInt(&bigint_space, dg.module);
@@ -3847,141 +3844,137 @@ pub const DeclGen = struct {
     fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
         const mod = dg.module;
         const target = mod.getTarget();
-        return switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {
-            .int => dg.lowerIntAsPtr(ptr_val),
-            .ptr => |ptr| switch (ptr.addr) {
-                .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),
-                .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),
-                .int => |int| dg.lowerIntAsPtr(int.toValue()),
-                .eu_payload => |eu_ptr| {
-                    const parent_llvm_ptr = try dg.lowerParentPtr(eu_ptr.toValue(), true);
-
-                    const eu_ty = mod.intern_pool.typeOf(eu_ptr).toType().childType(mod);
-                    const payload_ty = eu_ty.errorUnionPayload(mod);
-                    if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
-                        // In this case, we represent pointer to error union the same as pointer
-                        // to the payload.
-                        return parent_llvm_ptr;
-                    }
+        return switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
+            .decl => |decl| dg.lowerParentPtrDecl(ptr_val, decl),
+            .mut_decl => |mut_decl| dg.lowerParentPtrDecl(ptr_val, mut_decl.decl),
+            .int => |int| dg.lowerIntAsPtr(int.toValue()),
+            .eu_payload => |eu_ptr| {
+                const parent_llvm_ptr = try dg.lowerParentPtr(eu_ptr.toValue(), true);
+
+                const eu_ty = mod.intern_pool.typeOf(eu_ptr).toType().childType(mod);
+                const payload_ty = eu_ty.errorUnionPayload(mod);
+                if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+                    // In this case, we represent pointer to error union the same as pointer
+                    // to the payload.
+                    return parent_llvm_ptr;
+                }
 
-                    const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;
-                    const llvm_u32 = dg.context.intType(32);
-                    const indices: [2]*llvm.Value = .{
-                        llvm_u32.constInt(0, .False),
-                        llvm_u32.constInt(payload_offset, .False),
-                    };
-                    const eu_llvm_ty = try dg.lowerType(eu_ty);
-                    return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
-                },
-                .opt_payload => |opt_ptr| {
-                    const parent_llvm_ptr = try dg.lowerParentPtr(opt_ptr.toValue(), true);
+                const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;
+                const llvm_u32 = dg.context.intType(32);
+                const indices: [2]*llvm.Value = .{
+                    llvm_u32.constInt(0, .False),
+                    llvm_u32.constInt(payload_offset, .False),
+                };
+                const eu_llvm_ty = try dg.lowerType(eu_ty);
+                return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+            },
+            .opt_payload => |opt_ptr| {
+                const parent_llvm_ptr = try dg.lowerParentPtr(opt_ptr.toValue(), true);
 
-                    const opt_ty = mod.intern_pool.typeOf(opt_ptr).toType().childType(mod);
-                    const payload_ty = opt_ty.optionalChild(mod);
-                    if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or
-                        payload_ty.optionalReprIsPayload(mod))
-                    {
-                        // In this case, we represent pointer to optional the same as pointer
-                        // to the payload.
-                        return parent_llvm_ptr;
-                    }
+                const opt_ty = mod.intern_pool.typeOf(opt_ptr).toType().childType(mod);
+                const payload_ty = opt_ty.optionalChild(mod);
+                if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or
+                    payload_ty.optionalReprIsPayload(mod))
+                {
+                    // In this case, we represent pointer to optional the same as pointer
+                    // to the payload.
+                    return parent_llvm_ptr;
+                }
 
-                    const llvm_u32 = dg.context.intType(32);
-                    const indices: [2]*llvm.Value = .{
-                        llvm_u32.constInt(0, .False),
-                        llvm_u32.constInt(0, .False),
-                    };
-                    const opt_llvm_ty = try dg.lowerType(opt_ty);
-                    return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
-                },
-                .comptime_field => unreachable,
-                .elem => |elem_ptr| {
-                    const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.base.toValue(), true);
+                const llvm_u32 = dg.context.intType(32);
+                const indices: [2]*llvm.Value = .{
+                    llvm_u32.constInt(0, .False),
+                    llvm_u32.constInt(0, .False),
+                };
+                const opt_llvm_ty = try dg.lowerType(opt_ty);
+                return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+            },
+            .comptime_field => unreachable,
+            .elem => |elem_ptr| {
+                const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.base.toValue(), true);
 
-                    const llvm_usize = try dg.lowerType(Type.usize);
-                    const indices: [1]*llvm.Value = .{
-                        llvm_usize.constInt(elem_ptr.index, .False),
-                    };
-                    const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);
-                    const elem_llvm_ty = try dg.lowerType(elem_ty);
-                    return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
-                },
-                .field => |field_ptr| {
-                    const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.base.toValue(), byte_aligned);
-                    const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
-
-                    const field_index = @intCast(u32, field_ptr.index);
-                    const llvm_u32 = dg.context.intType(32);
-                    switch (parent_ty.zigTypeTag(mod)) {
-                        .Union => {
-                            if (parent_ty.containerLayout(mod) == .Packed) {
-                                return parent_llvm_ptr;
-                            }
+                const llvm_usize = try dg.lowerType(Type.usize);
+                const indices: [1]*llvm.Value = .{
+                    llvm_usize.constInt(elem_ptr.index, .False),
+                };
+                const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);
+                const elem_llvm_ty = try dg.lowerType(elem_ty);
+                return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+            },
+            .field => |field_ptr| {
+                const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.base.toValue(), byte_aligned);
+                const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
+
+                const field_index = @intCast(u32, field_ptr.index);
+                const llvm_u32 = dg.context.intType(32);
+                switch (parent_ty.zigTypeTag(mod)) {
+                    .Union => {
+                        if (parent_ty.containerLayout(mod) == .Packed) {
+                            return parent_llvm_ptr;
+                        }
 
-                            const layout = parent_ty.unionGetLayout(mod);
-                            if (layout.payload_size == 0) {
-                                // In this case a pointer to the union and a pointer to any
-                                // (void) payload is the same.
-                                return parent_llvm_ptr;
-                            }
-                            const llvm_pl_index = if (layout.tag_size == 0)
-                                0
-                            else
-                                @boolToInt(layout.tag_align >= layout.payload_align);
-                            const indices: [2]*llvm.Value = .{
-                                llvm_u32.constInt(0, .False),
-                                llvm_u32.constInt(llvm_pl_index, .False),
+                        const layout = parent_ty.unionGetLayout(mod);
+                        if (layout.payload_size == 0) {
+                            // In this case a pointer to the union and a pointer to any
+                            // (void) payload is the same.
+                            return parent_llvm_ptr;
+                        }
+                        const llvm_pl_index = if (layout.tag_size == 0)
+                            0
+                        else
+                            @boolToInt(layout.tag_align >= layout.payload_align);
+                        const indices: [2]*llvm.Value = .{
+                            llvm_u32.constInt(0, .False),
+                            llvm_u32.constInt(llvm_pl_index, .False),
+                        };
+                        const parent_llvm_ty = try dg.lowerType(parent_ty);
+                        return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+                    },
+                    .Struct => {
+                        if (parent_ty.containerLayout(mod) == .Packed) {
+                            if (!byte_aligned) return parent_llvm_ptr;
+                            const llvm_usize = dg.context.intType(target.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(mod).values()[0..field_index]) |field| {
+                                    if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+                                    b += @intCast(usize, field.ty.bitSize(mod));
+                                }
+                                break :b b;
                             };
-                            const parent_llvm_ty = try dg.lowerType(parent_ty);
-                            return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
-                        },
-                        .Struct => {
-                            if (parent_ty.containerLayout(mod) == .Packed) {
-                                if (!byte_aligned) return parent_llvm_ptr;
-                                const llvm_usize = dg.context.intType(target.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(mod).values()[0..field_index]) |field| {
-                                        if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
-                                        b += @intCast(usize, field.ty.bitSize(mod));
-                                    }
-                                    break :b b;
-                                };
-                                const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
-                                const field_addr = base_addr.constAdd(byte_offset);
-                                const final_llvm_ty = dg.context.pointerType(0);
-                                return field_addr.constIntToPtr(final_llvm_ty);
-                            }
+                            const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
+                            const field_addr = base_addr.constAdd(byte_offset);
+                            const final_llvm_ty = dg.context.pointerType(0);
+                            return field_addr.constIntToPtr(final_llvm_ty);
+                        }
 
-                            const parent_llvm_ty = try dg.lowerType(parent_ty);
-                            if (llvmField(parent_ty, field_index, mod)) |llvm_field| {
-                                const indices: [2]*llvm.Value = .{
-                                    llvm_u32.constInt(0, .False),
-                                    llvm_u32.constInt(llvm_field.index, .False),
-                                };
-                                return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
-                            } else {
-                                const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);
-                                const indices: [1]*llvm.Value = .{llvm_index};
-                                return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
-                            }
-                        },
-                        .Pointer => {
-                            assert(parent_ty.isSlice(mod));
+                        const parent_llvm_ty = try dg.lowerType(parent_ty);
+                        if (llvmField(parent_ty, field_index, mod)) |llvm_field| {
                             const indices: [2]*llvm.Value = .{
                                 llvm_u32.constInt(0, .False),
-                                llvm_u32.constInt(field_index, .False),
+                                llvm_u32.constInt(llvm_field.index, .False),
                             };
-                            const parent_llvm_ty = try dg.lowerType(parent_ty);
                             return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
-                        },
-                        else => unreachable,
-                    }
-                },
+                        } else {
+                            const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);
+                            const indices: [1]*llvm.Value = .{llvm_index};
+                            return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+                        }
+                    },
+                    .Pointer => {
+                        assert(parent_ty.isSlice(mod));
+                        const indices: [2]*llvm.Value = .{
+                            llvm_u32.constInt(0, .False),
+                            llvm_u32.constInt(field_index, .False),
+                        };
+                        const parent_llvm_ty = try dg.lowerType(parent_ty);
+                        return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
+                    },
+                    else => unreachable,
+                }
             },
-            else => unreachable,
         };
     }