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}