Commit 21bf3b8066

Robin Voetter <robin@voetter.nl>
2021-10-26 00:51:46
stage2: runtime c pointer null comparison
1 parent 4eb7b28
Changed files (2)
src
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);
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,
         }
     }