Commit 188902a710

Andrew Kelley <andrew@ziglang.org>
2022-09-12 06:48:52
Sema: introduce Type.ptrAlignmentAdvanced
I'm not sure why the other commits in this branch caused this fix to be necessary. Also, there seems to be more fixes necessary before tests will pass.
1 parent f16855b
Changed files (2)
src/Sema.zig
@@ -17575,30 +17575,30 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
     const operand_coerced = try sema.coerce(block, Type.usize, operand_res, operand_src);
 
     const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
-    const type_res = try sema.resolveType(block, src, extra.lhs);
-    try sema.checkPtrType(block, type_src, type_res);
-    try sema.resolveTypeLayout(block, src, type_res.elemType2());
-    const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());
+    const ptr_ty = try sema.resolveType(block, src, extra.lhs);
+    const elem_ty = ptr_ty.elemType2();
+    try sema.checkPtrType(block, type_src, ptr_ty);
     const target = sema.mod.getTarget();
+    const ptr_align = try ptr_ty.ptrAlignmentAdvanced(target, sema.kit(block, src));
 
     if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
         const addr = val.toUnsignedInt(target);
-        if (!type_res.isAllowzeroPtr() and addr == 0)
-            return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res.fmt(sema.mod)});
+        if (!ptr_ty.isAllowzeroPtr() and addr == 0)
+            return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(sema.mod)});
         if (addr != 0 and addr % ptr_align != 0)
-            return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res.fmt(sema.mod)});
+            return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)});
 
         const val_payload = try sema.arena.create(Value.Payload.U64);
         val_payload.* = .{
             .base = .{ .tag = .int_u64 },
             .data = addr,
         };
-        return sema.addConstant(type_res, Value.initPayload(&val_payload.base));
+        return sema.addConstant(ptr_ty, Value.initPayload(&val_payload.base));
     }
 
     try sema.requireRuntimeBlock(block, src, operand_src);
-    if (block.wantSafety() and try sema.typeHasRuntimeBits(block, sema.src, type_res.elemType2())) {
-        if (!type_res.isAllowzeroPtr()) {
+    if (block.wantSafety() and try sema.typeHasRuntimeBits(block, sema.src, elem_ty)) {
+        if (!ptr_ty.isAllowzeroPtr()) {
             const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
             try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);
         }
@@ -17618,7 +17618,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
             try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment);
         }
     }
-    return block.addBitCast(type_res, operand_coerced);
+    return block.addBitCast(ptr_ty, operand_coerced);
 }
 
 fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
src/type.zig
@@ -2715,8 +2715,12 @@ pub const Type = extern union {
     }
 
     /// Returns 0 if the pointer is naturally aligned and the element type is 0-bit.
-    pub fn ptrAlignment(self: Type, target: Target) u32 {
-        switch (self.tag()) {
+    pub fn ptrAlignment(ty: Type, target: Target) u32 {
+        return ptrAlignmentAdvanced(ty, target, null) catch unreachable;
+    }
+
+    pub fn ptrAlignmentAdvanced(ty: Type, target: Target, sema_kit: ?Module.WipAnalysis) !u32 {
+        switch (ty.tag()) {
             .single_const_pointer,
             .single_mut_pointer,
             .many_const_pointer,
@@ -2728,8 +2732,12 @@ pub const Type = extern union {
             .optional_single_const_pointer,
             .optional_single_mut_pointer,
             => {
-                const child_type = self.cast(Payload.ElemType).?.data;
-                return child_type.abiAlignment(target);
+                const child_type = ty.cast(Payload.ElemType).?.data;
+                if (sema_kit) |sk| {
+                    const res = try child_type.abiAlignmentAdvanced(target, .{ .sema_kit = sk });
+                    return res.scalar;
+                }
+                return (child_type.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar;
             },
 
             .manyptr_u8,
@@ -2740,14 +2748,17 @@ pub const Type = extern union {
             => return 1,
 
             .pointer => {
-                const ptr_info = self.castTag(.pointer).?.data;
+                const ptr_info = ty.castTag(.pointer).?.data;
                 if (ptr_info.@"align" != 0) {
                     return ptr_info.@"align";
+                } else if (sema_kit) |sk| {
+                    const res = try ptr_info.pointee_type.abiAlignmentAdvanced(target, .{ .sema_kit = sk });
+                    return res.scalar;
                 } else {
-                    return ptr_info.pointee_type.abiAlignment(target);
+                    return (ptr_info.pointee_type.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar;
                 }
             },
-            .optional => return self.castTag(.optional).?.data.ptrAlignment(target),
+            .optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(target, sema_kit),
 
             else => unreachable,
         }