master
 1const builtin = @import("builtin");
 2const std = @import("std");
 3const expect = std.testing.expect;
 4
 5test "anyopaque extern symbol" {
 6    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
 7    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
 8    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 9
10    const a = @extern(*anyopaque, .{ .name = "a_mystery_symbol" });
11    const b: *i32 = @ptrCast(@alignCast(a));
12    try expect(b.* == 1234);
13}
14
15export var a_mystery_symbol: i32 = 1234;
16
17test "function extern symbol" {
18    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
19    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
20
21    const a = @extern(*const fn () callconv(.c) i32, .{ .name = "a_mystery_function" });
22    try expect(a() == 4567);
23}
24
25export fn a_mystery_function() i32 {
26    return 4567;
27}
28
29test "function extern symbol matches extern decl" {
30    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
31    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
32
33    const S = struct {
34        extern fn another_mystery_function() u32;
35        const same_thing = @extern(*const fn () callconv(.c) u32, .{ .name = "another_mystery_function" });
36    };
37    try expect(S.another_mystery_function() == 12345);
38    try expect(S.same_thing() == 12345);
39}
40
41export fn another_mystery_function() u32 {
42    return 12345;
43}
44
45extern fn c_extern_function() [*c]u32;
46
47test "coerce extern function types" {
48    const S = struct {
49        export fn c_extern_function() [*c]u32 {
50            return null;
51        }
52    };
53    _ = S;
54
55    _ = @as(fn () callconv(.c) ?*u32, c_extern_function);
56}
57
58fn a_function(func: fn () callconv(.c) void) void {
59    _ = func;
60}
61
62test "pass extern function to function" {
63    a_function(struct {
64        extern fn an_extern_function() void;
65    }.an_extern_function);
66    a_function(@extern(*const fn () callconv(.c) void, .{ .name = "an_extern_function" }).*);
67}
68
69export fn an_extern_function() void {}