master
  1const builtin = @import("builtin");
  2const std = @import("std");
  3const expect = std.testing.expect;
  4const expectEqual = std.testing.expectEqual;
  5const maxInt = std.math.maxInt;
  6
  7test "@intCast i32 to u7" {
  8    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
  9    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 10    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 11    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 12
 13    var x: u128 = maxInt(u128);
 14    var y: i32 = 120;
 15    _ = .{ &x, &y };
 16    const z = x >> @as(u7, @intCast(y));
 17    try expect(z == 0xff);
 18}
 19
 20test "coerce i8 to i32 and @intCast back" {
 21    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 22    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 23
 24    var x: i8 = -5;
 25    var y: i32 = -5;
 26    _ = .{ &x, &y };
 27    try expect(y == x);
 28
 29    var x2: i32 = -5;
 30    var y2: i8 = -5;
 31    _ = .{ &x2, &y2 };
 32    try expect(y2 == @as(i8, @intCast(x2)));
 33}
 34
 35test "coerce non byte-sized integers accross 32bits boundary" {
 36    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
 37
 38    {
 39        var v: u21 = 6417;
 40        _ = &v;
 41        const a: u32 = v;
 42        const b: u64 = v;
 43        const c: u64 = a;
 44        var w: u64 = 0x1234567812345678;
 45        _ = &w;
 46        const d: u21 = @truncate(w);
 47        const e: u60 = d;
 48        try expectEqual(@as(u32, 6417), a);
 49        try expectEqual(@as(u64, 6417), b);
 50        try expectEqual(@as(u64, 6417), c);
 51        try expectEqual(@as(u21, 0x145678), d);
 52        try expectEqual(@as(u60, 0x145678), e);
 53    }
 54
 55    {
 56        var v: u10 = 234;
 57        _ = &v;
 58        const a: u32 = v;
 59        const b: u64 = v;
 60        const c: u64 = a;
 61        var w: u64 = 0x1234567812345678;
 62        _ = &w;
 63        const d: u10 = @truncate(w);
 64        const e: u60 = d;
 65        try expectEqual(@as(u32, 234), a);
 66        try expectEqual(@as(u64, 234), b);
 67        try expectEqual(@as(u64, 234), c);
 68        try expectEqual(@as(u21, 0x278), d);
 69        try expectEqual(@as(u60, 0x278), e);
 70    }
 71    {
 72        var v: u7 = 11;
 73        _ = &v;
 74        const a: u32 = v;
 75        const b: u64 = v;
 76        const c: u64 = a;
 77        var w: u64 = 0x1234567812345678;
 78        _ = &w;
 79        const d: u7 = @truncate(w);
 80        const e: u60 = d;
 81        try expectEqual(@as(u32, 11), a);
 82        try expectEqual(@as(u64, 11), b);
 83        try expectEqual(@as(u64, 11), c);
 84        try expectEqual(@as(u21, 0x78), d);
 85        try expectEqual(@as(u60, 0x78), e);
 86    }
 87
 88    {
 89        var v: i21 = -6417;
 90        _ = &v;
 91        const a: i32 = v;
 92        const b: i64 = v;
 93        const c: i64 = a;
 94        var w: i64 = -12345;
 95        _ = &w;
 96        const d: i21 = @intCast(w);
 97        const e: i60 = d;
 98        try expectEqual(@as(i32, -6417), a);
 99        try expectEqual(@as(i64, -6417), b);
100        try expectEqual(@as(i64, -6417), c);
101        try expectEqual(@as(i21, -12345), d);
102        try expectEqual(@as(i60, -12345), e);
103    }
104
105    {
106        var v: i10 = -234;
107        _ = &v;
108        const a: i32 = v;
109        const b: i64 = v;
110        const c: i64 = a;
111        var w: i64 = -456;
112        _ = &w;
113        const d: i10 = @intCast(w);
114        const e: i60 = d;
115        try expectEqual(@as(i32, -234), a);
116        try expectEqual(@as(i64, -234), b);
117        try expectEqual(@as(i64, -234), c);
118        try expectEqual(@as(i10, -456), d);
119        try expectEqual(@as(i60, -456), e);
120    }
121    {
122        var v: i7 = -11;
123        _ = &v;
124        const a: i32 = v;
125        const b: i64 = v;
126        const c: i64 = a;
127        var w: i64 = -42;
128        _ = &w;
129        const d: i7 = @intCast(w);
130        const e: i60 = d;
131        try expectEqual(@as(i32, -11), a);
132        try expectEqual(@as(i64, -11), b);
133        try expectEqual(@as(i64, -11), c);
134        try expectEqual(@as(i7, -42), d);
135        try expectEqual(@as(i60, -42), e);
136    }
137}
138
139const Piece = packed struct {
140    color: Color,
141    type: Type,
142
143    const Type = enum(u3) { KING, QUEEN, BISHOP, KNIGHT, ROOK, PAWN };
144    const Color = enum(u1) { WHITE, BLACK };
145
146    fn charToPiece(c: u8) !@This() {
147        return .{
148            .type = try charToPieceType(c),
149            .color = if (std.ascii.isUpper(c)) Color.WHITE else Color.BLACK,
150        };
151    }
152
153    fn charToPieceType(c: u8) !Type {
154        return switch (std.ascii.toLower(c)) {
155            'p' => .PAWN,
156            'k' => .KING,
157            'q' => .QUEEN,
158            'b' => .BISHOP,
159            'n' => .KNIGHT,
160            'r' => .ROOK,
161            else => error.UnexpectedCharError,
162        };
163    }
164};
165
166// Originally reported at https://github.com/ziglang/zig/issues/14200
167test "load non byte-sized optional value" {
168    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
169    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
170    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
171
172    // note: this bug is triggered by the == operator, expectEqual will hide it
173    const opt: ?Piece = try Piece.charToPiece('p');
174    try expect(opt.?.type == .PAWN);
175    try expect(opt.?.color == .BLACK);
176
177    var p: Piece = undefined;
178    @as(*u8, @ptrCast(&p)).* = 0b11111011;
179    try expect(p.type == .PAWN);
180    try expect(p.color == .BLACK);
181}
182
183test "load non byte-sized value in struct" {
184    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
185    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
186    if (builtin.cpu.arch.endian() != .little) return error.SkipZigTest; // packed struct TODO
187    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
188
189    // note: this bug is triggered by the == operator, expectEqual will hide it
190    // using ptrCast not to depend on unitialised memory state
191
192    var struct0: struct {
193        p: Piece,
194        int: u8,
195    } = undefined;
196    @as(*u8, @ptrCast(&struct0.p)).* = 0b11111011;
197    try expect(struct0.p.type == .PAWN);
198    try expect(struct0.p.color == .BLACK);
199
200    var struct1: packed struct {
201        p0: Piece,
202        p1: Piece,
203        pad: u1,
204        p2: Piece,
205    } = undefined;
206    @as(*u8, @ptrCast(&struct1.p0)).* = 0b11111011;
207    struct1.p1 = try Piece.charToPiece('p');
208    struct1.p2 = try Piece.charToPiece('p');
209    try expect(struct1.p0.type == .PAWN);
210    try expect(struct1.p0.color == .BLACK);
211    try expect(struct1.p1.type == .PAWN);
212    try expect(struct1.p1.color == .BLACK);
213    try expect(struct1.p2.type == .PAWN);
214    try expect(struct1.p2.color == .BLACK);
215}
216
217test "load non byte-sized value in union" {
218    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
219    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
220    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
221    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
222    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
223
224    // note: this bug is triggered by the == operator, expectEqual will hide it
225    // using ptrCast not to depend on unitialised memory state
226
227    var union0: packed union {
228        p: packed struct(u8) {
229            a: Piece,
230            b: u4,
231        },
232        int: u8,
233    } = .{ .int = 0 };
234    union0.int = 0b11111011;
235    try expect(union0.p.a.type == .PAWN);
236    try expect(union0.p.a.color == .BLACK);
237
238    var union1: union {
239        p: packed struct(u8) {
240            a: Piece,
241            b: u4,
242        },
243        int: u8,
244    } = .{ .p = .{ .a = .{ .color = .WHITE, .type = .KING }, .b = 0 } };
245    @as(*u8, @ptrCast(&union1.p.a)).* = 0b11111011;
246    try expect(union1.p.a.type == .PAWN);
247    try expect(union1.p.a.color == .BLACK);
248
249    var pieces: [3]Piece = undefined;
250    @as(*u8, @ptrCast(&pieces[1])).* = 0b11111011;
251    try expect(pieces[1].type == .PAWN);
252    try expect(pieces[1].color == .BLACK);
253}