authorgravatar for reserveblue@protonmail.comdrew <reserveblue@protonmail.com> 2021-11-15 17:57:48-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-16 16:51:31-07:00
log0249344a479a8eb51637c04fdecd947445ece0d5
treeab6f40562728736a469fa9e2bbd09f9694aa442c
parentf33af8f071a1782d222067e48b68eaed5d1a05a8

cast -> cast_llvm, cast_c -> cast (doesn't work on LLVM backend)


4 files changed, 299 insertions(+), 299 deletions(-)

test/behavior.zig+2-2
......@@ -19,7 +19,7 @@ test {
1919 _ = @import("behavior/bugs/4769_b.zig");
2020 _ = @import("behavior/bugs/6850.zig");
2121 _ = @import("behavior/call.zig");
22 _ = @import("behavior/cast_c.zig");
22 _ = @import("behavior/cast.zig");
2323 _ = @import("behavior/defer.zig");
2424 _ = @import("behavior/enum.zig");
2525 _ = @import("behavior/hasdecl.zig");
......@@ -52,7 +52,7 @@ test {
5252 _ = @import("behavior/bugs/1741.zig");
5353 _ = @import("behavior/bugs/2006.zig");
5454 _ = @import("behavior/bugs/3112.zig");
55 _ = @import("behavior/cast.zig");
55 _ = @import("behavior/cast_llvm.zig");
5656 _ = @import("behavior/error.zig");
5757 _ = @import("behavior/eval.zig");
5858 _ = @import("behavior/floatop.zig");
test/behavior/cast.zig+230-37
......@@ -2,18 +2,95 @@ const std = @import("std");
22const expect = std.testing.expect;
33const mem = std.mem;
44const maxInt = std.math.maxInt;
5const native_endian = @import("builtin").target.cpu.arch.endian();
65
7test "pointer reinterpret const float to int" {
8 // The hex representation is 0x3fe3333333333303.
9 const float: f64 = 5.99999999999994648725e-01;
10 const float_ptr = &float;
11 const int_ptr = @ptrCast(*const i32, float_ptr);
12 const int_val = int_ptr.*;
13 if (native_endian == .Little)
14 try expect(int_val == 0x33333303)
15 else
16 try expect(int_val == 0x3fe33333);
6test "int to ptr cast" {
7 const x = @as(usize, 13);
8 const y = @intToPtr(*u8, x);
9 const z = @ptrToInt(y);
10 try expect(z == 13);
11}
12
13test "integer literal to pointer cast" {
14 const vga_mem = @intToPtr(*u16, 0xB8000);
15 try expect(@ptrToInt(vga_mem) == 0xB8000);
16}
17
18test "peer type resolution: ?T and T" {
19 try expect(peerTypeTAndOptionalT(true, false).? == 0);
20 try expect(peerTypeTAndOptionalT(false, false).? == 3);
21 comptime {
22 try expect(peerTypeTAndOptionalT(true, false).? == 0);
23 try expect(peerTypeTAndOptionalT(false, false).? == 3);
24 }
25}
26fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
27 if (c) {
28 return if (b) null else @as(usize, 0);
29 }
30
31 return @as(usize, 3);
32}
33
34test "resolve undefined with integer" {
35 try testResolveUndefWithInt(true, 1234);
36 comptime try testResolveUndefWithInt(true, 1234);
37}
38fn testResolveUndefWithInt(b: bool, x: i32) !void {
39 const value = if (b) x else undefined;
40 if (b) {
41 try expect(value == x);
42 }
43}
44
45test "@intCast i32 to u7" {
46 var x: u128 = maxInt(u128);
47 var y: i32 = 120;
48 var z = x >> @intCast(u7, y);
49 try expect(z == 0xff);
50}
51
52test "@intCast to comptime_int" {
53 try expect(@intCast(comptime_int, 0) == 0);
54}
55
56test "implicit cast comptime numbers to any type when the value fits" {
57 const a: u64 = 255;
58 var b: u8 = a;
59 try expect(b == 255);
60}
61
62test "implicit cast comptime_int to comptime_float" {
63 comptime try expect(@as(comptime_float, 10) == @as(f32, 10));
64 try expect(2 == 2.0);
65}
66
67test "comptime_int @intToFloat" {
68 {
69 const result = @intToFloat(f16, 1234);
70 try expect(@TypeOf(result) == f16);
71 try expect(result == 1234.0);
72 }
73 {
74 const result = @intToFloat(f32, 1234);
75 try expect(@TypeOf(result) == f32);
76 try expect(result == 1234.0);
77 }
78 {
79 const result = @intToFloat(f64, 1234);
80 try expect(@TypeOf(result) == f64);
81 try expect(result == 1234.0);
82 }
83 {
84 const result = @intToFloat(f128, 1234);
85 try expect(@TypeOf(result) == f128);
86 try expect(result == 1234.0);
87 }
88 // big comptime_int (> 64 bits) to f128 conversion
89 {
90 const result = @intToFloat(f128, 0x1_0000_0000_0000_0000);
91 try expect(@TypeOf(result) == f128);
92 try expect(result == 0x1_0000_0000_0000_0000.0);
93 }
1794}
1895
1996test "@floatToInt" {
......@@ -22,46 +99,162 @@ test "@floatToInt" {
2299}
23100
24101fn testFloatToInts() !void {
25 try expectFloatToInt(f16, 255.1, u8, 255);
26 try expectFloatToInt(f16, 127.2, i8, 127);
27 try expectFloatToInt(f16, -128.2, i8, -128);
102 const x = @as(i32, 1e4);
103 try expect(x == 10000);
104 const y = @floatToInt(i32, @as(f32, 1e4));
105 try expect(y == 10000);
106 try expectFloatToInt(f32, 255.1, u8, 255);
107 try expectFloatToInt(f32, 127.2, i8, 127);
108 try expectFloatToInt(f32, -128.2, i8, -128);
28109}
29110
30111fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void {
31112 try expect(@floatToInt(I, f) == i);
32113}
33114
34test "implicit cast from [*]T to ?*c_void" {
35 var a = [_]u8{ 3, 2, 1 };
36 var runtime_zero: usize = 0;
37 incrementVoidPtrArray(a[runtime_zero..].ptr, 3);
38 try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));
115test "implicitly cast indirect pointer to maybe-indirect pointer" {
116 const S = struct {
117 const Self = @This();
118 x: u8,
119 fn constConst(p: *const *const Self) u8 {
120 return p.*.x;
121 }
122 fn maybeConstConst(p: ?*const *const Self) u8 {
123 return p.?.*.x;
124 }
125 fn constConstConst(p: *const *const *const Self) u8 {
126 return p.*.*.x;
127 }
128 fn maybeConstConstConst(p: ?*const *const *const Self) u8 {
129 return p.?.*.*.x;
130 }
131 };
132 const s = S{ .x = 42 };
133 const p = &s;
134 const q = &p;
135 const r = &q;
136 try expect(42 == S.constConst(q));
137 try expect(42 == S.maybeConstConst(q));
138 try expect(42 == S.constConstConst(r));
139 try expect(42 == S.maybeConstConstConst(r));
39140}
40141
41fn incrementVoidPtrArray(array: ?*c_void, len: usize) void {
42 var n: usize = 0;
43 while (n < len) : (n += 1) {
44 @ptrCast([*]u8, array.?)[n] += 1;
142test "@intCast comptime_int" {
143 const result = @intCast(i32, 1234);
144 try expect(@TypeOf(result) == i32);
145 try expect(result == 1234);
146}
147
148test "@floatCast comptime_int and comptime_float" {
149 {
150 const result = @floatCast(f16, 1234);
151 try expect(@TypeOf(result) == f16);
152 try expect(result == 1234.0);
153 }
154 {
155 const result = @floatCast(f16, 1234.0);
156 try expect(@TypeOf(result) == f16);
157 try expect(result == 1234.0);
45158 }
159 {
160 const result = @floatCast(f32, 1234);
161 try expect(@TypeOf(result) == f32);
162 try expect(result == 1234.0);
163 }
164 {
165 const result = @floatCast(f32, 1234.0);
166 try expect(@TypeOf(result) == f32);
167 try expect(result == 1234.0);
168 }
169}
170
171test "coerce undefined to optional" {
172 try expect(MakeType(void).getNull() == null);
173 try expect(MakeType(void).getNonNull() != null);
174}
175
176fn MakeType(comptime T: type) type {
177 return struct {
178 fn getNull() ?T {
179 return null;
180 }
181
182 fn getNonNull() ?T {
183 return @as(T, undefined);
184 }
185 };
186}
187
188test "implicit cast from *[N]T to [*c]T" {
189 var x: [4]u16 = [4]u16{ 0, 1, 2, 3 };
190 var y: [*c]u16 = &x;
191
192 try expect(std.mem.eql(u16, x[0..4], y[0..4]));
193 x[0] = 8;
194 y[3] = 6;
195 try expect(std.mem.eql(u16, x[0..4], y[0..4]));
196}
197
198test "*usize to *void" {
199 var i = @as(usize, 0);
200 var v = @ptrCast(*void, &i);
201 v.* = {};
46202}
47203
48test "compile time int to ptr of function" {
49 try foobar(FUNCTION_CONSTANT);
204test "@intToEnum passed a comptime_int to an enum with one item" {
205 const E = enum { A };
206 const x = @intToEnum(E, 0);
207 try expect(x == E.A);
50208}
51209
52pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize));
53pub const PFN_void = fn (*c_void) callconv(.C) void;
210test "@intCast to u0 and use the result" {
211 const S = struct {
212 fn doTheTest(zero: u1, one: u1, bigzero: i32) !void {
213 try expect((one << @intCast(u0, bigzero)) == 1);
214 try expect((zero << @intCast(u0, bigzero)) == 0);
215 }
216 };
217 try S.doTheTest(0, 1, 0);
218 comptime try S.doTheTest(0, 1, 0);
219}
220
221test "peer result null and comptime_int" {
222 const S = struct {
223 fn blah(n: i32) ?i32 {
224 if (n == 0) {
225 return null;
226 } else if (n < 0) {
227 return -1;
228 } else {
229 return 1;
230 }
231 }
232 };
233
234 try expect(S.blah(0) == null);
235 comptime try expect(S.blah(0) == null);
236 try expect(S.blah(10).? == 1);
237 comptime try expect(S.blah(10).? == 1);
238 try expect(S.blah(-10).? == -1);
239 comptime try expect(S.blah(-10).? == -1);
240}
54241
55fn foobar(func: PFN_void) !void {
56 try std.testing.expect(@ptrToInt(func) == maxInt(usize));
242test "*const ?[*]const T to [*c]const [*c]const T" {
243 var array = [_]u8{ 'o', 'k' };
244 const opt_array_ptr: ?[*]const u8 = &array;
245 const a: *const ?[*]const u8 = &opt_array_ptr;
246 const b: [*c]const [*c]const u8 = a;
247 try expect(b.*[0] == 'o');
248 try expect(b[0][1] == 'k');
57249}
58250
59test "implicit ptr to *c_void" {
60 var a: u32 = 1;
61 var ptr: *align(@alignOf(u32)) c_void = &a;
62 var b: *u32 = @ptrCast(*u32, ptr);
63 try expect(b.* == 1);
64 var ptr2: ?*align(@alignOf(u32)) c_void = &a;
65 var c: *u32 = @ptrCast(*u32, ptr2.?);
66 try expect(c.* == 1);
251test "array coersion to undefined at runtime" {
252 @setRuntimeSafety(true);
253
254 var array = [4]u8{ 3, 4, 5, 6 };
255 var undefined_val = [4]u8{ 0xAA, 0xAA, 0xAA, 0xAA };
256
257 try expect(std.mem.eql(u8, &array, &array));
258 array = undefined;
259 try expect(std.mem.eql(u8, &array, &undefined_val));
67260}
test/behavior/cast_c.zig deleted-260
......@@ -1,260 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const mem = std.mem;
4const maxInt = std.math.maxInt;
5
6test "int to ptr cast" {
7 const x = @as(usize, 13);
8 const y = @intToPtr(*u8, x);
9 const z = @ptrToInt(y);
10 try expect(z == 13);
11}
12
13test "integer literal to pointer cast" {
14 const vga_mem = @intToPtr(*u16, 0xB8000);
15 try expect(@ptrToInt(vga_mem) == 0xB8000);
16}
17
18test "peer type resolution: ?T and T" {
19 try expect(peerTypeTAndOptionalT(true, false).? == 0);
20 try expect(peerTypeTAndOptionalT(false, false).? == 3);
21 comptime {
22 try expect(peerTypeTAndOptionalT(true, false).? == 0);
23 try expect(peerTypeTAndOptionalT(false, false).? == 3);
24 }
25}
26fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
27 if (c) {
28 return if (b) null else @as(usize, 0);
29 }
30
31 return @as(usize, 3);
32}
33
34test "resolve undefined with integer" {
35 try testResolveUndefWithInt(true, 1234);
36 comptime try testResolveUndefWithInt(true, 1234);
37}
38fn testResolveUndefWithInt(b: bool, x: i32) !void {
39 const value = if (b) x else undefined;
40 if (b) {
41 try expect(value == x);
42 }
43}
44
45test "@intCast i32 to u7" {
46 var x: u128 = maxInt(u128);
47 var y: i32 = 120;
48 var z = x >> @intCast(u7, y);
49 try expect(z == 0xff);
50}
51
52test "@intCast to comptime_int" {
53 try expect(@intCast(comptime_int, 0) == 0);
54}
55
56test "implicit cast comptime numbers to any type when the value fits" {
57 const a: u64 = 255;
58 var b: u8 = a;
59 try expect(b == 255);
60}
61
62test "implicit cast comptime_int to comptime_float" {
63 comptime try expect(@as(comptime_float, 10) == @as(f32, 10));
64 try expect(2 == 2.0);
65}
66
67test "comptime_int @intToFloat" {
68 {
69 const result = @intToFloat(f16, 1234);
70 try expect(@TypeOf(result) == f16);
71 try expect(result == 1234.0);
72 }
73 {
74 const result = @intToFloat(f32, 1234);
75 try expect(@TypeOf(result) == f32);
76 try expect(result == 1234.0);
77 }
78 {
79 const result = @intToFloat(f64, 1234);
80 try expect(@TypeOf(result) == f64);
81 try expect(result == 1234.0);
82 }
83 {
84 const result = @intToFloat(f128, 1234);
85 try expect(@TypeOf(result) == f128);
86 try expect(result == 1234.0);
87 }
88 // big comptime_int (> 64 bits) to f128 conversion
89 {
90 const result = @intToFloat(f128, 0x1_0000_0000_0000_0000);
91 try expect(@TypeOf(result) == f128);
92 try expect(result == 0x1_0000_0000_0000_0000.0);
93 }
94}
95
96test "@floatToInt" {
97 try testFloatToInts();
98 comptime try testFloatToInts();
99}
100
101fn testFloatToInts() !void {
102 const x = @as(i32, 1e4);
103 try expect(x == 10000);
104 const y = @floatToInt(i32, @as(f32, 1e4));
105 try expect(y == 10000);
106 try expectFloatToInt(f32, 255.1, u8, 255);
107 try expectFloatToInt(f32, 127.2, i8, 127);
108 try expectFloatToInt(f32, -128.2, i8, -128);
109}
110
111fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void {
112 try expect(@floatToInt(I, f) == i);
113}
114
115test "implicitly cast indirect pointer to maybe-indirect pointer" {
116 const S = struct {
117 const Self = @This();
118 x: u8,
119 fn constConst(p: *const *const Self) u8 {
120 return p.*.x;
121 }
122 fn maybeConstConst(p: ?*const *const Self) u8 {
123 return p.?.*.x;
124 }
125 fn constConstConst(p: *const *const *const Self) u8 {
126 return p.*.*.x;
127 }
128 fn maybeConstConstConst(p: ?*const *const *const Self) u8 {
129 return p.?.*.*.x;
130 }
131 };
132 const s = S{ .x = 42 };
133 const p = &s;
134 const q = &p;
135 const r = &q;
136 try expect(42 == S.constConst(q));
137 try expect(42 == S.maybeConstConst(q));
138 try expect(42 == S.constConstConst(r));
139 try expect(42 == S.maybeConstConstConst(r));
140}
141
142test "@intCast comptime_int" {
143 const result = @intCast(i32, 1234);
144 try expect(@TypeOf(result) == i32);
145 try expect(result == 1234);
146}
147
148test "@floatCast comptime_int and comptime_float" {
149 {
150 const result = @floatCast(f16, 1234);
151 try expect(@TypeOf(result) == f16);
152 try expect(result == 1234.0);
153 }
154 {
155 const result = @floatCast(f16, 1234.0);
156 try expect(@TypeOf(result) == f16);
157 try expect(result == 1234.0);
158 }
159 {
160 const result = @floatCast(f32, 1234);
161 try expect(@TypeOf(result) == f32);
162 try expect(result == 1234.0);
163 }
164 {
165 const result = @floatCast(f32, 1234.0);
166 try expect(@TypeOf(result) == f32);
167 try expect(result == 1234.0);
168 }
169}
170
171test "coerce undefined to optional" {
172 try expect(MakeType(void).getNull() == null);
173 try expect(MakeType(void).getNonNull() != null);
174}
175
176fn MakeType(comptime T: type) type {
177 return struct {
178 fn getNull() ?T {
179 return null;
180 }
181
182 fn getNonNull() ?T {
183 return @as(T, undefined);
184 }
185 };
186}
187
188test "implicit cast from *[N]T to [*c]T" {
189 var x: [4]u16 = [4]u16{ 0, 1, 2, 3 };
190 var y: [*c]u16 = &x;
191
192 try expect(std.mem.eql(u16, x[0..4], y[0..4]));
193 x[0] = 8;
194 y[3] = 6;
195 try expect(std.mem.eql(u16, x[0..4], y[0..4]));
196}
197
198test "*usize to *void" {
199 var i = @as(usize, 0);
200 var v = @ptrCast(*void, &i);
201 v.* = {};
202}
203
204test "@intToEnum passed a comptime_int to an enum with one item" {
205 const E = enum { A };
206 const x = @intToEnum(E, 0);
207 try expect(x == E.A);
208}
209
210test "@intCast to u0 and use the result" {
211 const S = struct {
212 fn doTheTest(zero: u1, one: u1, bigzero: i32) !void {
213 try expect((one << @intCast(u0, bigzero)) == 1);
214 try expect((zero << @intCast(u0, bigzero)) == 0);
215 }
216 };
217 try S.doTheTest(0, 1, 0);
218 comptime try S.doTheTest(0, 1, 0);
219}
220
221test "peer result null and comptime_int" {
222 const S = struct {
223 fn blah(n: i32) ?i32 {
224 if (n == 0) {
225 return null;
226 } else if (n < 0) {
227 return -1;
228 } else {
229 return 1;
230 }
231 }
232 };
233
234 try expect(S.blah(0) == null);
235 comptime try expect(S.blah(0) == null);
236 try expect(S.blah(10).? == 1);
237 comptime try expect(S.blah(10).? == 1);
238 try expect(S.blah(-10).? == -1);
239 comptime try expect(S.blah(-10).? == -1);
240}
241
242test "*const ?[*]const T to [*c]const [*c]const T" {
243 var array = [_]u8{ 'o', 'k' };
244 const opt_array_ptr: ?[*]const u8 = &array;
245 const a: *const ?[*]const u8 = &opt_array_ptr;
246 const b: [*c]const [*c]const u8 = a;
247 try expect(b.*[0] == 'o');
248 try expect(b[0][1] == 'k');
249}
250
251test "array coersion to undefined at runtime" {
252 @setRuntimeSafety(true);
253
254 var array = [4]u8{ 3, 4, 5, 6 };
255 var undefined_val = [4]u8{ 0xAA, 0xAA, 0xAA, 0xAA };
256
257 try expect(std.mem.eql(u8, &array, &array));
258 array = undefined;
259 try expect(std.mem.eql(u8, &array, &undefined_val));
260}
test/behavior/cast_llvm.zig created+67
......@@ -0,0 +1,67 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const mem = std.mem;
4const maxInt = std.math.maxInt;
5const native_endian = @import("builtin").target.cpu.arch.endian();
6
7test "pointer reinterpret const float to int" {
8 // The hex representation is 0x3fe3333333333303.
9 const float: f64 = 5.99999999999994648725e-01;
10 const float_ptr = &float;
11 const int_ptr = @ptrCast(*const i32, float_ptr);
12 const int_val = int_ptr.*;
13 if (native_endian == .Little)
14 try expect(int_val == 0x33333303)
15 else
16 try expect(int_val == 0x3fe33333);
17}
18
19test "@floatToInt" {
20 try testFloatToInts();
21 comptime try testFloatToInts();
22}
23
24fn testFloatToInts() !void {
25 try expectFloatToInt(f16, 255.1, u8, 255);
26 try expectFloatToInt(f16, 127.2, i8, 127);
27 try expectFloatToInt(f16, -128.2, i8, -128);
28}
29
30fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void {
31 try expect(@floatToInt(I, f) == i);
32}
33
34test "implicit cast from [*]T to ?*c_void" {
35 var a = [_]u8{ 3, 2, 1 };
36 var runtime_zero: usize = 0;
37 incrementVoidPtrArray(a[runtime_zero..].ptr, 3);
38 try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));
39}
40
41fn incrementVoidPtrArray(array: ?*c_void, len: usize) void {
42 var n: usize = 0;
43 while (n < len) : (n += 1) {
44 @ptrCast([*]u8, array.?)[n] += 1;
45 }
46}
47
48test "compile time int to ptr of function" {
49 try foobar(FUNCTION_CONSTANT);
50}
51
52pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize));
53pub const PFN_void = fn (*c_void) callconv(.C) void;
54
55fn foobar(func: PFN_void) !void {
56 try std.testing.expect(@ptrToInt(func) == maxInt(usize));
57}
58
59test "implicit ptr to *c_void" {
60 var a: u32 = 1;
61 var ptr: *align(@alignOf(u32)) c_void = &a;
62 var b: *u32 = @ptrCast(*u32, ptr);
63 try expect(b.* == 1);
64 var ptr2: ?*align(@alignOf(u32)) c_void = &a;
65 var c: *u32 = @ptrCast(*u32, ptr2.?);
66 try expect(c.* == 1);
67}