Commit 560baf67ce

Veikka Tuominen <git@vexu.eu>
2022-08-22 09:54:07
Sema: fix implicit cast from extern fn to fn ptr
Closes #12570
1 parent b0bcd4a
Changed files (2)
src
test
behavior
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);
             }
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);
+}