| author | |
| committer | |
| log | c3364b372f4fa67a681d599f1a7ddcd4c0154fd1 |
| tree | fcc8851c14f859322b13be77a3ec9e3c7a33c4a1 |
| parent | 47388feec678b012a02e617b87ff90e84b03bcb7 |
| parent | d28f24d1d139c33ddfc2e8b763d9d18c933ef6d6 |
| signature |
add behavior test coverage for stage1 issues8 files changed, 141 insertions(+), 0 deletions(-)
test/behavior.zig+1| ... | ... | @@ -149,6 +149,7 @@ test { |
| 149 | 149 | _ = @import("behavior/byval_arg_var.zig"); |
| 150 | 150 | _ = @import("behavior/c_char_signedness.zig"); |
| 151 | 151 | _ = @import("behavior/call.zig"); |
| 152 | _ = @import("behavior/call_tail.zig"); | |
| 152 | 153 | _ = @import("behavior/cast.zig"); |
| 153 | 154 | _ = @import("behavior/cast_int.zig"); |
| 154 | 155 | _ = @import("behavior/comptime_memory.zig"); |
test/behavior/call_tail.zig created+59| ... | ... | @@ -0,0 +1,59 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | var base: usize = undefined; | |
| 6 | var result_off: [7]usize = undefined; | |
| 7 | var result_len: [7]usize = undefined; | |
| 8 | var result_index: usize = 0; | |
| 9 | ||
| 10 | noinline 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 | ||
| 33 | test "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 | 189 | }; |
| 190 | 190 | try expect(S.foo() == 5); |
| 191 | 191 | } |
| 192 | ||
| 193 | // Originally reported at https://github.com/ziglang/zig/issues/10591 | |
| 194 | const defer_assign = switch (block: { | |
| 195 | var x = 0; | |
| 196 | defer x = 1; | |
| 197 | break :block x; | |
| 198 | }) { | |
| 199 | else => |i| i, | |
| 200 | }; | |
| 201 | comptime { | |
| 202 | if (defer_assign != 0) @compileError("defer_assign failed!"); | |
| 203 | } |
test/behavior/eval.zig+10| ... | ... | @@ -1703,3 +1703,13 @@ test "@inComptime" { |
| 1703 | 1703 | try expectEqual(false, S.inComptime()); |
| 1704 | 1704 | try expectEqual(true, comptime S.inComptime()); |
| 1705 | 1705 | } |
| 1706 | ||
| 1707 | // comptime partial array assign | |
| 1708 | comptime { | |
| 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 | 640 | var s = packed struct { x: u4, y: u4 }{ .x = x, .y = if (x > 0) x else undefined }; |
| 641 | 641 | try expectEqual(x, s.x); |
| 642 | 642 | } |
| 643 | ||
| 644 | test "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 | 284 | _ = x; |
| 285 | 285 | } |
| 286 | 286 | } |
| 287 | ||
| 288 | test "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 | 797 | } |
| 798 | 798 | } |
| 799 | 799 | } |
| 800 | ||
| 801 | test "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 | 1692 | try expectEqual(@as(u20, 456), bp.*); |
| 1693 | 1693 | try expectEqual(@as(u20, 789), cp.*); |
| 1694 | 1694 | } |
| 1695 | ||
| 1696 | test "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 | } |