Skip to content

Commit 5ed8bd5

Browse files
alexrpmlugg
authored andcommitted
Sema: Fix some ptr alignment checks to handle a potential ISA tag bit.
Closes ziglang#23570.
1 parent e7b4636 commit 5ed8bd5

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

src/Sema.zig

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,3 +596,13 @@ test "function pointer @intFromPtr/@ptrFromInt roundtrip" {
596596

597597
try std.testing.expectEqual(nothing_ptr, nothing_ptr2);
598598
}
599+
600+
test "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+
}

0 commit comments

Comments
 (0)