authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-09-11 21:48:52-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-09-12 18:13:24-07:00
log188902a710a64b08762d7731aab81cb695322184
tree177ba4a0edb07fe1751a749f8cc30d7f533e29f6
parentf16855b9d70c747423ee81f27d619694856d365b

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.

2 files changed, 29 insertions(+), 18 deletions(-)

src/Sema.zig+11-11
......@@ -17575,30 +17575,30 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1757517575 const operand_coerced = try sema.coerce(block, Type.usize, operand_res, operand_src);
1757617576
1757717577 const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
17578 const type_res = try sema.resolveType(block, src, extra.lhs);
17579 try sema.checkPtrType(block, type_src, type_res);
17580 try sema.resolveTypeLayout(block, src, type_res.elemType2());
17581 const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());
17578 const ptr_ty = try sema.resolveType(block, src, extra.lhs);
17579 const elem_ty = ptr_ty.elemType2();
17580 try sema.checkPtrType(block, type_src, ptr_ty);
1758217581 const target = sema.mod.getTarget();
17582 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(target, sema.kit(block, src));
1758317583
1758417584 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
1758517585 const addr = val.toUnsignedInt(target);
17586 if (!type_res.isAllowzeroPtr() and addr == 0)
17587 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res.fmt(sema.mod)});
17586 if (!ptr_ty.isAllowzeroPtr() and addr == 0)
17587 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(sema.mod)});
1758817588 if (addr != 0 and addr % ptr_align != 0)
17589 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res.fmt(sema.mod)});
17589 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)});
1759017590
1759117591 const val_payload = try sema.arena.create(Value.Payload.U64);
1759217592 val_payload.* = .{
1759317593 .base = .{ .tag = .int_u64 },
1759417594 .data = addr,
1759517595 };
17596 return sema.addConstant(type_res, Value.initPayload(&val_payload.base));
17596 return sema.addConstant(ptr_ty, Value.initPayload(&val_payload.base));
1759717597 }
1759817598
1759917599 try sema.requireRuntimeBlock(block, src, operand_src);
17600 if (block.wantSafety() and try sema.typeHasRuntimeBits(block, sema.src, type_res.elemType2())) {
17601 if (!type_res.isAllowzeroPtr()) {
17600 if (block.wantSafety() and try sema.typeHasRuntimeBits(block, sema.src, elem_ty)) {
17601 if (!ptr_ty.isAllowzeroPtr()) {
1760217602 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
1760317603 try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);
1760417604 }
......@@ -17618,7 +17618,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1761817618 try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment);
1761917619 }
1762017620 }
17621 return block.addBitCast(type_res, operand_coerced);
17621 return block.addBitCast(ptr_ty, operand_coerced);
1762217622}
1762317623
1762417624fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
src/type.zig+18-7
......@@ -2715,8 +2715,12 @@ pub const Type = extern union {
27152715 }
27162716
27172717 /// Returns 0 if the pointer is naturally aligned and the element type is 0-bit.
2718 pub fn ptrAlignment(self: Type, target: Target) u32 {
2719 switch (self.tag()) {
2718 pub fn ptrAlignment(ty: Type, target: Target) u32 {
2719 return ptrAlignmentAdvanced(ty, target, null) catch unreachable;
2720 }
2721
2722 pub fn ptrAlignmentAdvanced(ty: Type, target: Target, sema_kit: ?Module.WipAnalysis) !u32 {
2723 switch (ty.tag()) {
27202724 .single_const_pointer,
27212725 .single_mut_pointer,
27222726 .many_const_pointer,
......@@ -2728,8 +2732,12 @@ pub const Type = extern union {
27282732 .optional_single_const_pointer,
27292733 .optional_single_mut_pointer,
27302734 => {
2731 const child_type = self.cast(Payload.ElemType).?.data;
2732 return child_type.abiAlignment(target);
2735 const child_type = ty.cast(Payload.ElemType).?.data;
2736 if (sema_kit) |sk| {
2737 const res = try child_type.abiAlignmentAdvanced(target, .{ .sema_kit = sk });
2738 return res.scalar;
2739 }
2740 return (child_type.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar;
27332741 },
27342742
27352743 .manyptr_u8,
......@@ -2740,14 +2748,17 @@ pub const Type = extern union {
27402748 => return 1,
27412749
27422750 .pointer => {
2743 const ptr_info = self.castTag(.pointer).?.data;
2751 const ptr_info = ty.castTag(.pointer).?.data;
27442752 if (ptr_info.@"align" != 0) {
27452753 return ptr_info.@"align";
2754 } else if (sema_kit) |sk| {
2755 const res = try ptr_info.pointee_type.abiAlignmentAdvanced(target, .{ .sema_kit = sk });
2756 return res.scalar;
27462757 } else {
2747 return ptr_info.pointee_type.abiAlignment(target);
2758 return (ptr_info.pointee_type.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar;
27482759 }
27492760 },
2750 .optional => return self.castTag(.optional).?.data.ptrAlignment(target),
2761 .optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(target, sema_kit),
27512762
27522763 else => unreachable,
27532764 }