Skip to content

Commit f1e43d1

Browse files
committed
Sema: emit cast to null panics for function pointers
Closes #14676
1 parent c3b30a0 commit f1e43d1

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

src/Sema.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19626,7 +19626,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1962619626
}
1962719627

1962819628
try sema.requireRuntimeBlock(block, src, operand_src);
19629-
if (block.wantSafety() and try sema.typeHasRuntimeBits(elem_ty)) {
19629+
if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag() == .Fn)) {
1963019630
if (!ptr_ty.isAllowzeroPtr()) {
1963119631
const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
1963219632
try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);
@@ -19852,7 +19852,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1985219852

1985319853
try sema.requireRuntimeBlock(block, src, null);
1985419854
if (block.wantSafety() and operand_ty.ptrAllowsZero() and !dest_ty.ptrAllowsZero() and
19855-
try sema.typeHasRuntimeBits(dest_ty.elemType2()))
19855+
(try sema.typeHasRuntimeBits(dest_ty.elemType2()) or dest_ty.elemType2().zigTypeTag() == .Fn))
1985619856
{
1985719857
const ptr_int = try block.addUnOp(.ptrtoint, ptr);
1985819858
const is_non_zero = try block.addBinOp(.cmp_neq, ptr_int, .zero_usize);
@@ -27718,7 +27718,7 @@ fn coerceCompatiblePtrs(
2771827718
try sema.requireRuntimeBlock(block, inst_src, null);
2771927719
const inst_allows_zero = inst_ty.zigTypeTag() != .Pointer or inst_ty.ptrAllowsZero();
2772027720
if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero() and
27721-
try sema.typeHasRuntimeBits(dest_ty.elemType2()))
27721+
(try sema.typeHasRuntimeBits(dest_ty.elemType2()) or dest_ty.elemType2().zigTypeTag() == .Fn))
2772227722
{
2772327723
const actual_ptr = if (inst_ty.isSlice())
2772427724
try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const std = @import("std");
2+
3+
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
4+
_ = stack_trace;
5+
if (std.mem.eql(u8, message, "cast causes pointer to be null")) {
6+
std.process.exit(0);
7+
}
8+
std.process.exit(1);
9+
}
10+
11+
fn getNullPtr() ?*const anyopaque {
12+
return null;
13+
}
14+
pub fn main() !void {
15+
const null_ptr: ?*const anyopaque = getNullPtr();
16+
const required_ptr: *align(1) const fn() void = @ptrCast(*align(1) const fn() void, null_ptr);
17+
_ = required_ptr;
18+
return error.TestFailed;
19+
}
20+
21+
// run
22+
// backend=llvm
23+
// target=native

0 commit comments

Comments
 (0)