authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-26 23:38:28-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-07-26 23:38:28-07:00
logc3364b372f4fa67a681d599f1a7ddcd4c0154fd1
treefcc8851c14f859322b13be77a3ec9e3c7a33c4a1
parent47388feec678b012a02e617b87ff90e84b03bcb7
parentd28f24d1d139c33ddfc2e8b763d9d18c933ef6d6
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #16572 from ziglang/stage1-test-coverage

add behavior test coverage for stage1 issues

8 files changed, 141 insertions(+), 0 deletions(-)

test/behavior.zig+1
...@@ -149,6 +149,7 @@ test {...@@ -149,6 +149,7 @@ test {
149 _ = @import("behavior/byval_arg_var.zig");149 _ = @import("behavior/byval_arg_var.zig");
150 _ = @import("behavior/c_char_signedness.zig");150 _ = @import("behavior/c_char_signedness.zig");
151 _ = @import("behavior/call.zig");151 _ = @import("behavior/call.zig");
152 _ = @import("behavior/call_tail.zig");
152 _ = @import("behavior/cast.zig");153 _ = @import("behavior/cast.zig");
153 _ = @import("behavior/cast_int.zig");154 _ = @import("behavior/cast_int.zig");
154 _ = @import("behavior/comptime_memory.zig");155 _ = @import("behavior/comptime_memory.zig");
test/behavior/call_tail.zig created+59
...@@ -0,0 +1,59 @@
1const builtin = @import("builtin");
2const std = @import("std");
3const expect = std.testing.expect;
4
5var base: usize = undefined;
6var result_off: [7]usize = undefined;
7var result_len: [7]usize = undefined;
8var result_index: usize = 0;
9
10noinline fn insertionSort(data: []u64) void {
11 result_off[result_index] = @intFromPtr(data.ptr) - base;
12 result_len[result_index] = data.len;
13 result_index += 1;
14 if (data.len > 1) {
15 var least_i: usize = 0;
16 var i: usize = 1;
17 while (i < data.len) : (i += 1) {
18 if (data[i] < data[least_i])
19 least_i = i;
20 }
21 std.mem.swap(u64, &data[0], &data[least_i]);
22
23 // there used to be a bug where
24 // `data[1..]` is created on the stack
25 // and pointed to by the first argument register
26 // then stack is invalidated by the tailcall and
27 // overwritten by callee
28 // https://github.com/ziglang/zig/issues/9703
29 return @call(.always_tail, insertionSort, .{data[1..]});
30 }
31}
32
33test "arguments pointed to on stack into tailcall" {
34 switch (builtin.cpu.arch) {
35 .wasm32, .mips, .mipsel, .powerpc, .powerpcle, .powerpc64le => return error.SkipZigTest,
36 else => {},
37 }
38 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
39 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
40
41 var data = [_]u64{ 1, 6, 2, 7, 1, 9, 3 };
42 base = @intFromPtr(&data);
43 insertionSort(data[0..]);
44 try expect(result_len[0] == 7);
45 try expect(result_len[1] == 6);
46 try expect(result_len[2] == 5);
47 try expect(result_len[3] == 4);
48 try expect(result_len[4] == 3);
49 try expect(result_len[5] == 2);
50 try expect(result_len[6] == 1);
51
52 try expect(result_off[0] == 0);
53 try expect(result_off[1] == 8);
54 try expect(result_off[2] == 16);
55 try expect(result_off[3] == 24);
56 try expect(result_off[4] == 32);
57 try expect(result_off[5] == 40);
58 try expect(result_off[6] == 48);
59}
test/behavior/defer.zig+12
...@@ -189,3 +189,15 @@ test "errdefer used in function that doesn't return an error" {...@@ -189,3 +189,15 @@ test "errdefer used in function that doesn't return an error" {
189 };189 };
190 try expect(S.foo() == 5);190 try expect(S.foo() == 5);
191}191}
192
193// Originally reported at https://github.com/ziglang/zig/issues/10591
194const defer_assign = switch (block: {
195 var x = 0;
196 defer x = 1;
197 break :block x;
198}) {
199 else => |i| i,
200};
201comptime {
202 if (defer_assign != 0) @compileError("defer_assign failed!");
203}
test/behavior/eval.zig+10
...@@ -1703,3 +1703,13 @@ test "@inComptime" {...@@ -1703,3 +1703,13 @@ test "@inComptime" {
1703 try expectEqual(false, S.inComptime());1703 try expectEqual(false, S.inComptime());
1704 try expectEqual(true, comptime S.inComptime());1704 try expectEqual(true, comptime S.inComptime());
1705}1705}
1706
1707// comptime partial array assign
1708comptime {
1709 var foo = [3]u8{ 0x55, 0x55, 0x55 };
1710 var bar = [2]u8{ 1, 2 };
1711 foo[0..2].* = bar;
1712 assert(foo[0] == 1);
1713 assert(foo[1] == 2);
1714 assert(foo[2] == 0x55);
1715}
test/behavior/packed-struct.zig+10
...@@ -640,3 +640,13 @@ test "store undefined to packed result location" {...@@ -640,3 +640,13 @@ test "store undefined to packed result location" {
640 var s = packed struct { x: u4, y: u4 }{ .x = x, .y = if (x > 0) x else undefined };640 var s = packed struct { x: u4, y: u4 }{ .x = x, .y = if (x > 0) x else undefined };
641 try expectEqual(x, s.x);641 try expectEqual(x, s.x);
642}642}
643
644test "bitcast back and forth" {
645 // Originally reported at https://github.com/ziglang/zig/issues/9914
646 const S = packed struct { one: u6, two: u1 };
647 const s = S{ .one = 0b110101, .two = 0b1 };
648 const u: u7 = @bitCast(s);
649 const s2: S = @bitCast(u);
650 try expect(s.one == s2.one);
651 try expect(s.two == s2.two);
652}
test/behavior/ptrcast.zig+9
...@@ -284,3 +284,12 @@ test "@ptrCast undefined value at comptime" {...@@ -284,3 +284,12 @@ test "@ptrCast undefined value at comptime" {
284 _ = x;284 _ = x;
285 }285 }
286}286}
287
288test "comptime @ptrCast with packed struct leaves value unmodified" {
289 const S = packed struct { three: u3 };
290 const st: S = .{ .three = 6 };
291 try expect(st.three == 6);
292 const p: *const [1]u3 = @ptrCast(&st);
293 try expect(p.*[0] == 6);
294 try expect(st.three == 6);
295}
test/behavior/switch.zig+19
...@@ -797,3 +797,22 @@ test "inline switch range that includes the maximum value of the switched type"...@@ -797,3 +797,22 @@ test "inline switch range that includes the maximum value of the switched type"
797 }797 }
798 }798 }
799}799}
800
801test "nested break ignores switch conditions and breaks instead" {
802 const S = struct {
803 fn register_to_address(ident: []const u8) !u8 {
804 const reg: u8 = if (std.mem.eql(u8, ident, "zero")) 0x00 else blk: {
805 break :blk switch (ident[0]) {
806 0x61 => (try std.fmt.parseInt(u8, ident[1..], 0)) + 1,
807 0x66 => (try std.fmt.parseInt(u8, ident[1..], 0)) + 1,
808 else => {
809 break :blk 0xFF;
810 },
811 };
812 };
813 return reg;
814 }
815 };
816 // Originally reported at https://github.com/ziglang/zig/issues/10196
817 try expect(0x01 == try S.register_to_address("a0"));
818}
test/behavior/union.zig+21
...@@ -1692,3 +1692,24 @@ test "packed union field pointer has correct alignment" {...@@ -1692,3 +1692,24 @@ test "packed union field pointer has correct alignment" {
1692 try expectEqual(@as(u20, 456), bp.*);1692 try expectEqual(@as(u20, 456), bp.*);
1693 try expectEqual(@as(u20, 789), cp.*);1693 try expectEqual(@as(u20, 789), cp.*);
1694}1694}
1695
1696test "union with 128 bit integer" {
1697 const ValueTag = enum { int, other };
1698
1699 const Value3 = union(ValueTag) {
1700 int: i128,
1701 other: bool,
1702 };
1703 var values: [2]Value3 = undefined;
1704 values[0] = .{ .int = 3 };
1705 values[1] = .{ .int = 4 };
1706
1707 var ok: usize = 0;
1708
1709 for (values) |val| {
1710 switch (val) {
1711 .int => ok += 1,
1712 else => return error.TestFailed,
1713 }
1714 }
1715}