1const std = @import("std");
2const builtin = @import("builtin");
3const expect = std.testing.expect;
4
5var pos = [2]f32{ 0.0, 0.0 };
6test "store to global array" {
7 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
9
10 try expect(pos[1] == 0.0);
11 pos = [2]f32{ 0.0, 1.0 };
12 try expect(pos[1] == 1.0);
13}
14
15var vpos = @Vector(2, f32){ 0.0, 0.0 };
16test "store to global vector" {
17 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
19
20 try expect(vpos[1] == 0.0);
21 vpos = @Vector(2, f32){ 0.0, 1.0 };
22 try expect(vpos[1] == 1.0);
23}
24
25test "slices pointing at the same address as global array." {
26 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
27 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
28 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
29
30 const S = struct {
31 const a = [_]u8{ 1, 2, 3 };
32
33 fn checkAddress(s: []const u8) !void {
34 for (s, 0..) |*i, j| {
35 try expect(i == &a[j]);
36 }
37 }
38 };
39
40 try S.checkAddress(&S.a);
41 try comptime S.checkAddress(&S.a);
42}
43
44test "global loads can affect liveness" {
45 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
46 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
47 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
48
49 const S = struct {
50 const ByRef = struct {
51 a: u32,
52 };
53
54 var global_ptr: *ByRef = undefined;
55
56 fn f() void {
57 global_ptr.* = .{ .a = 42 };
58 }
59 };
60
61 var x: S.ByRef = .{ .a = 1 };
62 S.global_ptr = &x;
63 const y = x;
64 S.f();
65 try std.testing.expect(y.a == 1);
66}
67
68test "global const can be self-referential" {
69 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
70
71 const S = struct {
72 self: *const @This(),
73 x: u32,
74
75 const foo: @This() = .{ .self = &foo, .x = 123 };
76 };
77
78 try std.testing.expect(S.foo.x == 123);
79 try std.testing.expect(S.foo.self.x == 123);
80 try std.testing.expect(S.foo.self.self.x == 123);
81 try std.testing.expect(S.foo.self == &S.foo);
82 try std.testing.expect(S.foo.self.self == &S.foo);
83}
84
85test "global var can be self-referential" {
86 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
87
88 const S = struct {
89 self: *@This(),
90 x: u32,
91
92 var foo: @This() = .{ .self = &foo, .x = undefined };
93 };
94
95 S.foo.x = 123;
96
97 try std.testing.expect(S.foo.x == 123);
98 try std.testing.expect(S.foo.self.x == 123);
99 try std.testing.expect(S.foo.self == &S.foo);
100
101 S.foo.self.x = 456;
102
103 try std.testing.expect(S.foo.x == 456);
104 try std.testing.expect(S.foo.self.x == 456);
105 try std.testing.expect(S.foo.self == &S.foo);
106
107 S.foo.self.self.x = 789;
108
109 try std.testing.expect(S.foo.x == 789);
110 try std.testing.expect(S.foo.self.x == 789);
111 try std.testing.expect(S.foo.self == &S.foo);
112}
113
114test "global const can be indirectly self-referential" {
115 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
116
117 const S = struct {
118 other: *const @This(),
119 x: u32,
120
121 const foo: @This() = .{ .other = &bar, .x = 123 };
122 const bar: @This() = .{ .other = &foo, .x = 456 };
123 };
124
125 try std.testing.expect(S.foo.x == 123);
126 try std.testing.expect(S.foo.other.x == 456);
127 try std.testing.expect(S.foo.other.other.x == 123);
128 try std.testing.expect(S.foo.other.other.other.x == 456);
129 try std.testing.expect(S.foo.other == &S.bar);
130 try std.testing.expect(S.foo.other.other == &S.foo);
131
132 try std.testing.expect(S.bar.x == 456);
133 try std.testing.expect(S.bar.other.x == 123);
134 try std.testing.expect(S.bar.other.other.x == 456);
135 try std.testing.expect(S.bar.other.other.other.x == 123);
136 try std.testing.expect(S.bar.other == &S.foo);
137 try std.testing.expect(S.bar.other.other == &S.bar);
138}
139
140test "global var can be indirectly self-referential" {
141 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
142
143 const S = struct {
144 other: *@This(),
145 x: u32,
146
147 var foo: @This() = .{ .other = &bar, .x = undefined };
148 var bar: @This() = .{ .other = &foo, .x = undefined };
149 };
150
151 S.foo.other.x = 123; // bar.x
152 S.foo.other.other.x = 456; // foo.x
153
154 try std.testing.expect(S.foo.x == 456);
155 try std.testing.expect(S.foo.other.x == 123);
156 try std.testing.expect(S.foo.other.other.x == 456);
157 try std.testing.expect(S.foo.other.other.other.x == 123);
158 try std.testing.expect(S.foo.other == &S.bar);
159 try std.testing.expect(S.foo.other.other == &S.foo);
160
161 S.bar.other.x = 111; // foo.x
162 S.bar.other.other.x = 222; // bar.x
163
164 try std.testing.expect(S.bar.x == 222);
165 try std.testing.expect(S.bar.other.x == 111);
166 try std.testing.expect(S.bar.other.other.x == 222);
167 try std.testing.expect(S.bar.other.other.other.x == 111);
168 try std.testing.expect(S.bar.other == &S.foo);
169 try std.testing.expect(S.bar.other.other == &S.bar);
170}
171
172pub const Callbacks = extern struct {
173 key_callback: *const fn (key: i32) callconv(.c) i32,
174};
175
176var callbacks: Callbacks = undefined;
177var callbacks_loaded: bool = false;
178
179test "function pointer field call on global extern struct, conditional on global" {
180 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
181
182 if (callbacks_loaded) {
183 try std.testing.expectEqual(42, callbacks.key_callback(42));
184 }
185}
186
187test "function pointer field call on global extern struct" {
188 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
189 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
190
191 const S = struct {
192 fn keyCallback(key: i32) callconv(.c) i32 {
193 return key;
194 }
195 };
196
197 callbacks = Callbacks{ .key_callback = S.keyCallback };
198 try std.testing.expectEqual(42, callbacks.key_callback(42));
199}