From 560baf67ce77de41da3d03183300cdf1b6d90567 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Mon, 22 Aug 2022 10:54:07 +0300 Subject: [PATCH] Sema: fix implicit cast from extern fn to fn ptr Closes #12570 --- src/Sema.zig | 2 +- test/behavior/fn.zig | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Sema.zig b/src/Sema.zig index 9538073e5c..42d5e96d3d 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -22564,7 +22564,7 @@ fn coerceExtra( // Function body to function pointer. if (inst_ty.zigTypeTag() == .Fn) { const fn_val = try sema.resolveConstValue(block, .unneeded, inst, undefined); - const fn_decl = fn_val.castTag(.function).?.data.owner_decl; + const fn_decl = fn_val.pointerDecl().?; const inst_as_ptr = try sema.analyzeDeclRef(fn_decl); return sema.coerce(block, dest_ty, inst_as_ptr, inst_src); } diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index d68cd89210..47ba63c429 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -422,3 +422,24 @@ test "import passed byref to function in return type" { var list = S.get(); try expect(list.items.len == 0); } + +test "implicit cast function to function ptr" { + if (builtin.zig_backend == .stage1) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + + const S1 = struct { + export fn someFunctionThatReturnsAValue() c_int { + return 123; + } + }; + var fnPtr1: *const fn () callconv(.C) c_int = S1.someFunctionThatReturnsAValue; + try expect(fnPtr1() == 123); + const S2 = struct { + extern fn someFunctionThatReturnsAValue() c_int; + }; + var fnPtr2: *const fn () callconv(.C) c_int = S2.someFunctionThatReturnsAValue; + try expect(fnPtr2() == 123); +}