authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-04-14 18:40:47+02:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-04-27 23:54:54+01:00
log5ed8bd5c85e34d200a504418ebd2fc3d902460ac
tree5315274c455873fadde58eb09c572324128e3dff
parente7b46363aea6e42c206cb7b1bd8c9b47a83d9045

Sema: Fix some ptr alignment checks to handle a potential ISA tag bit.

Closes #23570.

2 files changed, 26 insertions(+), 3 deletions(-)

src/Sema.zig+16-3
......@@ -22614,8 +22614,16 @@ fn ptrFromIntVal(
2261422614 const addr = try operand_val.toUnsignedIntSema(pt);
2261522615 if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0)
2261622616 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(pt)});
22617 if (addr != 0 and ptr_align != .none and !ptr_align.check(addr))
22618 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(pt)});
22617 if (addr != 0 and ptr_align != .none) {
22618 const masked_addr = if (ptr_ty.childType(zcu).fnPtrMaskOrNull(zcu)) |mask|
22619 addr & mask
22620 else
22621 addr;
22622
22623 if (!ptr_align.check(masked_addr)) {
22624 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(pt)});
22625 }
22626 }
2261922627
2262022628 return switch (ptr_ty.zigTypeTag(zcu)) {
2262122629 .optional => Value.fromInterned(try pt.intern(.{ .opt = .{
......@@ -23131,7 +23139,12 @@ fn ptrCastFull(
2313123139
2313223140 if (dest_align.compare(.gt, src_align)) {
2313323141 if (try ptr_val.getUnsignedIntSema(pt)) |addr| {
23134 if (!dest_align.check(addr)) {
23142 const masked_addr = if (Type.fromInterned(dest_info.child).fnPtrMaskOrNull(zcu)) |mask|
23143 addr & mask
23144 else
23145 addr;
23146
23147 if (!dest_align.check(masked_addr)) {
2313523148 return sema.fail(block, operand_src, "pointer address 0x{X} is not aligned to {d} bytes", .{
2313623149 addr,
2313723150 dest_align.toByteUnits().?,
test/behavior/align.zig+10
......@@ -596,3 +596,13 @@ test "function pointer @intFromPtr/@ptrFromInt roundtrip" {
596596
597597 try std.testing.expectEqual(nothing_ptr, nothing_ptr2);
598598}
599
600test "function pointer align mask" {
601 if (!(builtin.cpu.arch.isArm() or builtin.cpu.arch.isMIPS())) return error.SkipZigTest;
602
603 const a: *const fn () callconv(.c) void = @ptrFromInt(0x20202021);
604 _ = &a;
605
606 const b: *align(16) const fn () callconv(.c) void = @alignCast(a);
607 _ = &b;
608}