master
  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_sparc64) return error.SkipZigTest;
 46    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 47
 48    const S = struct {
 49        const ByRef = struct {
 50            a: u32,
 51        };
 52
 53        var global_ptr: *ByRef = undefined;
 54
 55        fn f() void {
 56            global_ptr.* = .{ .a = 42 };
 57        }
 58    };
 59
 60    var x: S.ByRef = .{ .a = 1 };
 61    S.global_ptr = &x;
 62    const y = x;
 63    S.f();
 64    try std.testing.expect(y.a == 1);
 65}
 66
 67test "global const can be self-referential" {
 68    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 69
 70    const S = struct {
 71        self: *const @This(),
 72        x: u32,
 73
 74        const foo: @This() = .{ .self = &foo, .x = 123 };
 75    };
 76
 77    try std.testing.expect(S.foo.x == 123);
 78    try std.testing.expect(S.foo.self.x == 123);
 79    try std.testing.expect(S.foo.self.self.x == 123);
 80    try std.testing.expect(S.foo.self == &S.foo);
 81    try std.testing.expect(S.foo.self.self == &S.foo);
 82}
 83
 84test "global var can be self-referential" {
 85    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 86
 87    const S = struct {
 88        self: *@This(),
 89        x: u32,
 90
 91        var foo: @This() = .{ .self = &foo, .x = undefined };
 92    };
 93
 94    S.foo.x = 123;
 95
 96    try std.testing.expect(S.foo.x == 123);
 97    try std.testing.expect(S.foo.self.x == 123);
 98    try std.testing.expect(S.foo.self == &S.foo);
 99
100    S.foo.self.x = 456;
101
102    try std.testing.expect(S.foo.x == 456);
103    try std.testing.expect(S.foo.self.x == 456);
104    try std.testing.expect(S.foo.self == &S.foo);
105
106    S.foo.self.self.x = 789;
107
108    try std.testing.expect(S.foo.x == 789);
109    try std.testing.expect(S.foo.self.x == 789);
110    try std.testing.expect(S.foo.self == &S.foo);
111}
112
113test "global const can be indirectly self-referential" {
114    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
115
116    const S = struct {
117        other: *const @This(),
118        x: u32,
119
120        const foo: @This() = .{ .other = &bar, .x = 123 };
121        const bar: @This() = .{ .other = &foo, .x = 456 };
122    };
123
124    try std.testing.expect(S.foo.x == 123);
125    try std.testing.expect(S.foo.other.x == 456);
126    try std.testing.expect(S.foo.other.other.x == 123);
127    try std.testing.expect(S.foo.other.other.other.x == 456);
128    try std.testing.expect(S.foo.other == &S.bar);
129    try std.testing.expect(S.foo.other.other == &S.foo);
130
131    try std.testing.expect(S.bar.x == 456);
132    try std.testing.expect(S.bar.other.x == 123);
133    try std.testing.expect(S.bar.other.other.x == 456);
134    try std.testing.expect(S.bar.other.other.other.x == 123);
135    try std.testing.expect(S.bar.other == &S.foo);
136    try std.testing.expect(S.bar.other.other == &S.bar);
137}
138
139test "global var can be indirectly self-referential" {
140    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
141
142    const S = struct {
143        other: *@This(),
144        x: u32,
145
146        var foo: @This() = .{ .other = &bar, .x = undefined };
147        var bar: @This() = .{ .other = &foo, .x = undefined };
148    };
149
150    S.foo.other.x = 123; // bar.x
151    S.foo.other.other.x = 456; // foo.x
152
153    try std.testing.expect(S.foo.x == 456);
154    try std.testing.expect(S.foo.other.x == 123);
155    try std.testing.expect(S.foo.other.other.x == 456);
156    try std.testing.expect(S.foo.other.other.other.x == 123);
157    try std.testing.expect(S.foo.other == &S.bar);
158    try std.testing.expect(S.foo.other.other == &S.foo);
159
160    S.bar.other.x = 111; // foo.x
161    S.bar.other.other.x = 222; // bar.x
162
163    try std.testing.expect(S.bar.x == 222);
164    try std.testing.expect(S.bar.other.x == 111);
165    try std.testing.expect(S.bar.other.other.x == 222);
166    try std.testing.expect(S.bar.other.other.other.x == 111);
167    try std.testing.expect(S.bar.other == &S.foo);
168    try std.testing.expect(S.bar.other.other == &S.bar);
169}
170
171pub const Callbacks = extern struct {
172    key_callback: *const fn (key: i32) callconv(.c) i32,
173};
174
175var callbacks: Callbacks = undefined;
176var callbacks_loaded: bool = false;
177
178test "function pointer field call on global extern struct, conditional on global" {
179    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
180
181    if (callbacks_loaded) {
182        try std.testing.expectEqual(42, callbacks.key_callback(42));
183    }
184}
185
186test "function pointer field call on global extern struct" {
187    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
188    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
189
190    const S = struct {
191        fn keyCallback(key: i32) callconv(.c) i32 {
192            return key;
193        }
194    };
195
196    callbacks = Callbacks{ .key_callback = S.keyCallback };
197    try std.testing.expectEqual(42, callbacks.key_callback(42));
198}