From 4eb7b28700b23d8465a36e364e60394b2a1da41b Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Mon, 25 Oct 2021 03:41:23 +0200 Subject: stage2: generate correct constants for zero-sized arrays --- src/codegen/llvm.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/codegen/llvm.zig') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 80f2d8b653..646633a90d 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -762,7 +762,7 @@ pub const DeclGen = struct { } const llvm_addrspace = dg.llvmAddressSpace(t.ptrAddressSpace()); const elem_ty = t.childType(); - const llvm_elem_ty = if (elem_ty.hasCodeGenBits()) + const llvm_elem_ty = if (elem_ty.hasCodeGenBits() or elem_ty.zigTypeTag() == .Array) try dg.llvmType(elem_ty) else dg.context.intType(8); @@ -1475,7 +1475,7 @@ pub const DeclGen = struct { } const llvm_type = try self.llvmType(tv.ty); - if (!tv.ty.childType().hasCodeGenBits()) { + if (!tv.ty.childType().hasCodeGenBits() or !decl.ty.hasCodeGenBits()) { return self.lowerPtrToVoid(tv.ty); } @@ -1497,7 +1497,7 @@ pub const DeclGen = struct { // for non-optional pointers. We also need to respect the alignment, even though // the address will never be dereferenced. const llvm_usize = try dg.llvmType(Type.usize); - const llvm_ptr_ty = dg.context.intType(8).pointerType(0); + const llvm_ptr_ty = try dg.llvmType(ptr_ty); if (alignment != 0) { return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty); } -- cgit v1.2.3 From 21bf3b80666c14c9b2a2e1ec984a6b4bb23a5bb7 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Tue, 26 Oct 2021 00:51:46 +0200 Subject: stage2: runtime c pointer null comparison --- src/codegen/llvm.zig | 11 ++++++----- src/type.zig | 6 +++++- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src/codegen/llvm.zig') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 646633a90d..1a4bada192 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -2450,6 +2450,12 @@ pub const FuncGen = struct { const operand = try self.resolveInst(un_op); const operand_ty = self.air.typeOf(un_op); const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; + if (optional_ty.isPtrLikeOptional()) { + const optional_llvm_ty = try self.dg.llvmType(optional_ty); + const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand; + return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), ""); + } + var buf: Type.Payload.ElemType = undefined; const payload_ty = optional_ty.optionalChild(&buf); if (!payload_ty.hasCodeGenBits()) { @@ -2459,11 +2465,6 @@ pub const FuncGen = struct { return operand; } } - if (optional_ty.isPtrLikeOptional()) { - const optional_llvm_ty = try self.dg.llvmType(optional_ty); - const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand; - return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), ""); - } if (operand_is_ptr or isByRef(optional_ty)) { const index_type = self.context.intType(32); diff --git a/src/type.zig b/src/type.zig index e77780d9ca..7ac235e68e 100644 --- a/src/type.zig +++ b/src/type.zig @@ -2347,11 +2347,13 @@ pub const Type = extern union { } } - /// Asserts that the type is an optional + /// Asserts that the type is an optional or a pointer that can be null. pub fn isPtrLikeOptional(self: Type) bool { switch (self.tag()) { .optional_single_const_pointer, .optional_single_mut_pointer, + .c_const_pointer, + .c_mut_pointer, => return true, .optional => { @@ -2367,6 +2369,8 @@ pub const Type = extern union { .Many, .One => return !info.@"allowzero", } }, + + .pointer => return self.castTag(.pointer).?.data.size == .C, else => unreachable, } } -- cgit v1.2.3