Sema: fix @intToPtr of zero value to optional pointer
Calling into coercion logic here is a little opaque, and more to the point wholly unnecessary. Instead, the (very short) logic is now implemented directly in Sema. Resolves: #16033
This commit is contained in:
@@ -6817,17 +6817,12 @@ pub fn errorSetFromUnsortedNames(
|
||||
return new_ty.toType();
|
||||
}
|
||||
|
||||
/// Supports optionals in addition to pointers.
|
||||
/// Supports only pointers, not pointer-like optionals.
|
||||
pub fn ptrIntValue(mod: *Module, ty: Type, x: u64) Allocator.Error!Value {
|
||||
return mod.getCoerced(try mod.intValue_u64(Type.usize, x), ty);
|
||||
}
|
||||
|
||||
/// Supports only pointers. See `ptrIntValue` for pointer-like optional support.
|
||||
pub fn ptrIntValue_ptronly(mod: *Module, ty: Type, x: u64) Allocator.Error!Value {
|
||||
assert(ty.zigTypeTag(mod) == .Pointer);
|
||||
const i = try intern(mod, .{ .ptr = .{
|
||||
.ty = ty.toIntern(),
|
||||
.addr = .{ .int = try mod.intValue_u64(Type.usize, x) },
|
||||
.addr = .{ .int = (try mod.intValue_u64(Type.usize, x)).toIntern() },
|
||||
} });
|
||||
return i.toValue();
|
||||
}
|
||||
|
||||
10
src/Sema.zig
10
src/Sema.zig
@@ -20846,7 +20846,15 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
if (addr != 0 and ptr_align != 0 and addr % ptr_align != 0)
|
||||
return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)});
|
||||
|
||||
return sema.addConstant(ptr_ty, try mod.ptrIntValue(ptr_ty, addr));
|
||||
const ptr_val = switch (ptr_ty.zigTypeTag(mod)) {
|
||||
.Optional => (try mod.intern(.{ .opt = .{
|
||||
.ty = ptr_ty.toIntern(),
|
||||
.val = if (addr == 0) .none else (try mod.ptrIntValue(ptr_ty.childType(mod), addr)).toIntern(),
|
||||
} })).toValue(),
|
||||
.Pointer => try mod.ptrIntValue(ptr_ty, addr),
|
||||
else => unreachable,
|
||||
};
|
||||
return sema.addConstant(ptr_ty, ptr_val);
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src, operand_src);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const expectEqual = std.testing.expectEqual;
|
||||
|
||||
test "casting integer address to function pointer" {
|
||||
addressToFunction();
|
||||
@@ -26,3 +28,21 @@ fn forceCompilerAnalyzeBranchHardCodedPtrDereference(x: bool) void {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
test "@intToPtr creates null 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 ptr = @intToPtr(?*u32, 0);
|
||||
try expectEqual(@as(?*u32, null), ptr);
|
||||
}
|
||||
|
||||
test "@intToPtr creates 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 ptr = @intToPtr(*allowzero u32, 0);
|
||||
try expectEqual(@as(usize, 0), @ptrToInt(ptr));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user