From 188902a710a64b08762d7731aab81cb695322184 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 11 Sep 2022 21:48:52 -0700 Subject: [PATCH] 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. --- src/Sema.zig | 22 +++++++++++----------- src/type.zig | 25 ++++++++++++++++++------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index f5e4402ea8..6e48fafeaf 100644 --- a/src/Sema.zig +++ b/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 { diff --git a/src/type.zig b/src/type.zig index ec7e155d4e..c72cf2be84 100644 --- a/src/type.zig +++ b/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, }