| author | |
| committer | |
| log | 0249344a479a8eb51637c04fdecd947445ece0d5 |
| tree | ab6f40562728736a469fa9e2bbd09f9694aa442c |
| parent | f33af8f071a1782d222067e48b68eaed5d1a05a8 |
4 files changed, 299 insertions(+), 299 deletions(-)
test/behavior.zig+2-2| ... | ... | @@ -19,7 +19,7 @@ test { |
| 19 | 19 | _ = @import("behavior/bugs/4769_b.zig"); |
| 20 | 20 | _ = @import("behavior/bugs/6850.zig"); |
| 21 | 21 | _ = @import("behavior/call.zig"); |
| 22 | _ = @import("behavior/cast_c.zig"); | |
| 22 | _ = @import("behavior/cast.zig"); | |
| 23 | 23 | _ = @import("behavior/defer.zig"); |
| 24 | 24 | _ = @import("behavior/enum.zig"); |
| 25 | 25 | _ = @import("behavior/hasdecl.zig"); |
| ... | ... | @@ -52,7 +52,7 @@ test { |
| 52 | 52 | _ = @import("behavior/bugs/1741.zig"); |
| 53 | 53 | _ = @import("behavior/bugs/2006.zig"); |
| 54 | 54 | _ = @import("behavior/bugs/3112.zig"); |
| 55 | _ = @import("behavior/cast.zig"); | |
| 55 | _ = @import("behavior/cast_llvm.zig"); | |
| 56 | 56 | _ = @import("behavior/error.zig"); |
| 57 | 57 | _ = @import("behavior/eval.zig"); |
| 58 | 58 | _ = @import("behavior/floatop.zig"); |
test/behavior/cast.zig+230-37| ... | ... | @@ -2,18 +2,95 @@ const std = @import("std"); |
| 2 | 2 | const expect = std.testing.expect; |
| 3 | 3 | const mem = std.mem; |
| 4 | 4 | const maxInt = std.math.maxInt; |
| 5 | const native_endian = @import("builtin").target.cpu.arch.endian(); | |
| 6 | 5 | |
| 7 | test "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); | |
| 6 | test "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 | ||
| 13 | test "integer literal to pointer cast" { | |
| 14 | const vga_mem = @intToPtr(*u16, 0xB8000); | |
| 15 | try expect(@ptrToInt(vga_mem) == 0xB8000); | |
| 16 | } | |
| 17 | ||
| 18 | test "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 | } | |
| 26 | fn 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 | ||
| 34 | test "resolve undefined with integer" { | |
| 35 | try testResolveUndefWithInt(true, 1234); | |
| 36 | comptime try testResolveUndefWithInt(true, 1234); | |
| 37 | } | |
| 38 | fn 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 | ||
| 45 | test "@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 | ||
| 52 | test "@intCast to comptime_int" { | |
| 53 | try expect(@intCast(comptime_int, 0) == 0); | |
| 54 | } | |
| 55 | ||
| 56 | test "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 | ||
| 62 | test "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 | ||
| 67 | test "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 | } | |
| 17 | 94 | } |
| 18 | 95 | |
| 19 | 96 | test "@floatToInt" { |
| ... | ... | @@ -22,46 +99,162 @@ test "@floatToInt" { |
| 22 | 99 | } |
| 23 | 100 | |
| 24 | 101 | fn 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); | |
| 28 | 109 | } |
| 29 | 110 | |
| 30 | 111 | fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void { |
| 31 | 112 | try expect(@floatToInt(I, f) == i); |
| 32 | 113 | } |
| 33 | 114 | |
| 34 | test "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 })); | |
| 115 | test "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)); | |
| 39 | 140 | } |
| 40 | 141 | |
| 41 | fn incrementVoidPtrArray(array: ?*c_void, len: usize) void { | |
| 42 | var n: usize = 0; | |
| 43 | while (n < len) : (n += 1) { | |
| 44 | @ptrCast([*]u8, array.?)[n] += 1; | |
| 142 | test "@intCast comptime_int" { | |
| 143 | const result = @intCast(i32, 1234); | |
| 144 | try expect(@TypeOf(result) == i32); | |
| 145 | try expect(result == 1234); | |
| 146 | } | |
| 147 | ||
| 148 | test "@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); | |
| 45 | 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 | ||
| 171 | test "coerce undefined to optional" { | |
| 172 | try expect(MakeType(void).getNull() == null); | |
| 173 | try expect(MakeType(void).getNonNull() != null); | |
| 174 | } | |
| 175 | ||
| 176 | fn 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 | ||
| 188 | test "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 | ||
| 198 | test "*usize to *void" { | |
| 199 | var i = @as(usize, 0); | |
| 200 | var v = @ptrCast(*void, &i); | |
| 201 | v.* = {}; | |
| 46 | 202 | } |
| 47 | 203 | |
| 48 | test "compile time int to ptr of function" { | |
| 49 | try foobar(FUNCTION_CONSTANT); | |
| 204 | test "@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); | |
| 50 | 208 | } |
| 51 | 209 | |
| 52 | pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize)); | |
| 53 | pub const PFN_void = fn (*c_void) callconv(.C) void; | |
| 210 | test "@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 | ||
| 221 | test "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 | } | |
| 54 | 241 | |
| 55 | fn foobar(func: PFN_void) !void { | |
| 56 | try std.testing.expect(@ptrToInt(func) == maxInt(usize)); | |
| 242 | test "*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'); | |
| 57 | 249 | } |
| 58 | 250 | |
| 59 | test "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); | |
| 251 | test "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)); | |
| 67 | 260 | } |
test/behavior/cast_c.zig deleted-260| ... | ... | @@ -1,260 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const mem = std.mem; | |
| 4 | const maxInt = std.math.maxInt; | |
| 5 | ||
| 6 | test "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 | ||
| 13 | test "integer literal to pointer cast" { | |
| 14 | const vga_mem = @intToPtr(*u16, 0xB8000); | |
| 15 | try expect(@ptrToInt(vga_mem) == 0xB8000); | |
| 16 | } | |
| 17 | ||
| 18 | test "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 | } | |
| 26 | fn 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 | ||
| 34 | test "resolve undefined with integer" { | |
| 35 | try testResolveUndefWithInt(true, 1234); | |
| 36 | comptime try testResolveUndefWithInt(true, 1234); | |
| 37 | } | |
| 38 | fn 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 | ||
| 45 | test "@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 | ||
| 52 | test "@intCast to comptime_int" { | |
| 53 | try expect(@intCast(comptime_int, 0) == 0); | |
| 54 | } | |
| 55 | ||
| 56 | test "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 | ||
| 62 | test "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 | ||
| 67 | test "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 | ||
| 96 | test "@floatToInt" { | |
| 97 | try testFloatToInts(); | |
| 98 | comptime try testFloatToInts(); | |
| 99 | } | |
| 100 | ||
| 101 | fn 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 | ||
| 111 | fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void { | |
| 112 | try expect(@floatToInt(I, f) == i); | |
| 113 | } | |
| 114 | ||
| 115 | test "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 | ||
| 142 | test "@intCast comptime_int" { | |
| 143 | const result = @intCast(i32, 1234); | |
| 144 | try expect(@TypeOf(result) == i32); | |
| 145 | try expect(result == 1234); | |
| 146 | } | |
| 147 | ||
| 148 | test "@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 | ||
| 171 | test "coerce undefined to optional" { | |
| 172 | try expect(MakeType(void).getNull() == null); | |
| 173 | try expect(MakeType(void).getNonNull() != null); | |
| 174 | } | |
| 175 | ||
| 176 | fn 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 | ||
| 188 | test "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 | ||
| 198 | test "*usize to *void" { | |
| 199 | var i = @as(usize, 0); | |
| 200 | var v = @ptrCast(*void, &i); | |
| 201 | v.* = {}; | |
| 202 | } | |
| 203 | ||
| 204 | test "@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 | ||
| 210 | test "@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 | ||
| 221 | test "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 | ||
| 242 | test "*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 | ||
| 251 | test "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 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const mem = std.mem; | |
| 4 | const maxInt = std.math.maxInt; | |
| 5 | const native_endian = @import("builtin").target.cpu.arch.endian(); | |
| 6 | ||
| 7 | test "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 | ||
| 19 | test "@floatToInt" { | |
| 20 | try testFloatToInts(); | |
| 21 | comptime try testFloatToInts(); | |
| 22 | } | |
| 23 | ||
| 24 | fn 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 | ||
| 30 | fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void { | |
| 31 | try expect(@floatToInt(I, f) == i); | |
| 32 | } | |
| 33 | ||
| 34 | test "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 | ||
| 41 | fn 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 | ||
| 48 | test "compile time int to ptr of function" { | |
| 49 | try foobar(FUNCTION_CONSTANT); | |
| 50 | } | |
| 51 | ||
| 52 | pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize)); | |
| 53 | pub const PFN_void = fn (*c_void) callconv(.C) void; | |
| 54 | ||
| 55 | fn foobar(func: PFN_void) !void { | |
| 56 | try std.testing.expect(@ptrToInt(func) == maxInt(usize)); | |
| 57 | } | |
| 58 | ||
| 59 | test "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 | } |