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