fix ptrFromInt

This commit is contained in:
David Rubin 2024-10-28 21:18:07 -07:00
parent 5ce17ecfa7
commit bfedbf8dab
No known key found for this signature in database
GPG Key ID: A4390FEB5F00C0A5
2 changed files with 42 additions and 8 deletions

View File

@ -23299,10 +23299,13 @@ fn ptrFromIntVal(
return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(pt)});
return switch (ptr_ty.zigTypeTag(zcu)) {
.optional => Value.fromInterned(try pt.intern(.{ .opt = .{
.optional => val: {
const is_null: bool = addr == 0 and !ptr_ty.childType(zcu).isAllowzeroPtr(zcu);
break :val Value.fromInterned(try pt.intern(.{ .opt = .{
.ty = ptr_ty.toIntern(),
.val = if (addr == 0) .none else (try pt.ptrIntValue(ptr_ty.childType(zcu), addr)).toIntern(),
} })),
.val = if (is_null) .none else (try pt.ptrIntValue(ptr_ty.childType(zcu), addr)).toIntern(),
} }));
},
.pointer => try pt.ptrIntValue(ptr_ty, addr),
else => unreachable,
};

View File

@ -1,5 +1,6 @@
const std = @import("std");
const builtin = @import("builtin");
const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
test "casting integer address to function pointer" {
@ -35,8 +36,15 @@ test "@ptrFromInt creates null pointer" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
const ptr = @as(?*u32, @ptrFromInt(0));
try expectEqual(@as(?*u32, null), ptr);
const S = struct {
fn doTest(addr: usize) !void {
const ptr: ?*u32 = @ptrFromInt(addr);
try expectEqual(null, ptr);
}
};
try S.doTest(0);
comptime try S.doTest(0);
}
test "@ptrFromInt creates allowzero zero pointer" {
@ -44,6 +52,29 @@ test "@ptrFromInt creates allowzero zero pointer" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
const ptr = @as(*allowzero u32, @ptrFromInt(0));
try expectEqual(@as(usize, 0), @intFromPtr(ptr));
const S = struct {
fn doTest(addr: usize) !void {
const ptr: *allowzero const u32 = @ptrFromInt(addr);
try expectEqual(addr, @intFromPtr(ptr));
}
};
try S.doTest(0);
comptime try S.doTest(0);
}
test "@ptrFromInt creates optional allowzero zero pointer" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
const S = struct {
fn doTest(addr: usize) !void {
const ptr: ?*allowzero const u32 = @ptrFromInt(addr);
try expect(ptr != null);
}
};
try S.doTest(0);
comptime try S.doTest(0);
}