authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-10 19:22:23-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-02-10 19:22:23-05:00
logf0400ad93eac984332c938b39e9c1627062d6b6a
tree408041de12ad2ba66bb139e2ca10d08297195469
parente139c41fd8955f873615b2c2434d162585c0e44c
parent9c6d416bec10b9edd88545287133921274af1d2f
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10857 from Luukdegram/wasm-tests

stage2: Wasm - implement field_ptr

7 files changed, 117 insertions(+), 32 deletions(-)

src/arch/wasm/CodeGen.zig+70-25
...@@ -1106,6 +1106,20 @@ pub const DeclGen = struct {...@@ -1106,6 +1106,20 @@ pub const DeclGen = struct {
1106 }1106 }
1107 return Result{ .appended = {} };1107 return Result{ .appended = {} };
1108 },1108 },
1109 .Float => {
1110 const float_bits = ty.floatBits(self.target());
1111 if (float_bits > 64) {
1112 return self.fail("Wasm TODO: Implement f80 and f128", .{});
1113 }
1114
1115 switch (float_bits) {
1116 16, 32 => try writer.writeIntLittle(u32, @bitCast(u32, val.toFloat(f32))),
1117 64 => try writer.writeIntLittle(u64, @bitCast(u64, val.toFloat(f64))),
1118 else => unreachable,
1119 }
1120
1121 return Result{ .appended = {} };
1122 },
1109 .Enum => {1123 .Enum => {
1110 var int_buffer: Value.Payload.U64 = undefined;1124 var int_buffer: Value.Payload.U64 = undefined;
1111 const int_val = val.enumToInt(ty, &int_buffer);1125 const int_val = val.enumToInt(ty, &int_buffer);
...@@ -1334,10 +1348,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu...@@ -1334,10 +1348,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu
1334 defer self.gpa.free(param_types);1348 defer self.gpa.free(param_types);
1335 fn_ty.fnParamTypes(param_types);1349 fn_ty.fnParamTypes(param_types);
1336 var result: CallWValues = .{1350 var result: CallWValues = .{
1337 .args = try self.gpa.alloc(WValue, param_types.len),1351 .args = &.{},
1338 .return_value = .none,1352 .return_value = .none,
1339 };1353 };
1340 errdefer self.gpa.free(result.args);1354 var args = std.ArrayList(WValue).init(self.gpa);
1355 defer args.deinit();
1356
1341 const ret_ty = fn_ty.fnReturnType();1357 const ret_ty = fn_ty.fnReturnType();
1342 // Check if we store the result as a pointer to the stack rather than1358 // Check if we store the result as a pointer to the stack rather than
1343 // by value1359 // by value
...@@ -1350,18 +1366,18 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu...@@ -1350,18 +1366,18 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) InnerError!CallWValu
1350 switch (cc) {1366 switch (cc) {
1351 .Naked => return result,1367 .Naked => return result,
1352 .Unspecified, .C => {1368 .Unspecified, .C => {
1353 for (param_types) |ty, ty_index| {1369 for (param_types) |ty| {
1354 if (!ty.hasRuntimeBits()) {1370 if (!ty.hasRuntimeBits()) {
1355 result.args[ty_index] = .{ .none = {} };
1356 continue;1371 continue;
1357 }1372 }
13581373
1359 result.args[ty_index] = .{ .local = self.local_index };1374 try args.append(.{ .local = self.local_index });
1360 self.local_index += 1;1375 self.local_index += 1;
1361 }1376 }
1362 },1377 },
1363 else => return self.fail("TODO implement function parameters for cc '{}' on wasm", .{cc}),1378 else => return self.fail("TODO implement function parameters for cc '{}' on wasm", .{cc}),
1364 }1379 }
1380 result.args = args.toOwnedSlice();
1365 return result;1381 return result;
1366}1382}
13671383
...@@ -2060,6 +2076,26 @@ fn airWrapBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {...@@ -2060,6 +2076,26 @@ fn airWrapBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {
20602076
2061fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {2077fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
2062 if (val.isUndefDeep()) return self.emitUndefined(ty);2078 if (val.isUndefDeep()) return self.emitUndefined(ty);
2079 if (val.castTag(.decl_ref)) |decl_ref| {
2080 const decl = decl_ref.data;
2081 decl.markAlive();
2082 const target_sym_index = decl.link.wasm.sym_index;
2083 if (ty.isSlice()) {
2084 var slice_len: Value.Payload.U64 = .{
2085 .base = .{ .tag = .int_u64 },
2086 .data = val.sliceLen(),
2087 };
2088 var slice_val: Value.Payload.Slice = .{
2089 .base = .{ .tag = .slice },
2090 .data = .{ .ptr = val.slicePtr(), .len = Value.initPayload(&slice_len.base) },
2091 };
2092 return self.lowerConstant(Value.initPayload(&slice_val.base), ty);
2093 } else if (decl.ty.zigTypeTag() == .Fn) {
2094 try self.bin_file.addTableFunction(target_sym_index);
2095 return WValue{ .function_index = target_sym_index };
2096 } else return WValue{ .memory = target_sym_index };
2097 }
2098
2063 switch (ty.zigTypeTag()) {2099 switch (ty.zigTypeTag()) {
2064 .Int => {2100 .Int => {
2065 const int_info = ty.intInfo(self.target);2101 const int_info = ty.intInfo(self.target);
...@@ -2084,25 +2120,6 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {...@@ -2084,25 +2120,6 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
2084 else => unreachable,2120 else => unreachable,
2085 },2121 },
2086 .Pointer => switch (val.tag()) {2122 .Pointer => switch (val.tag()) {
2087 .decl_ref => {
2088 const decl = val.castTag(.decl_ref).?.data;
2089 decl.markAlive();
2090 const target_sym_index = decl.link.wasm.sym_index;
2091 if (ty.isSlice()) {
2092 var slice_len: Value.Payload.U64 = .{
2093 .base = .{ .tag = .int_u64 },
2094 .data = val.sliceLen(),
2095 };
2096 var slice_val: Value.Payload.Slice = .{
2097 .base = .{ .tag = .slice },
2098 .data = .{ .ptr = val.slicePtr(), .len = Value.initPayload(&slice_len.base) },
2099 };
2100 return self.lowerConstant(Value.initPayload(&slice_val.base), ty);
2101 } else if (decl.ty.zigTypeTag() == .Fn) {
2102 try self.bin_file.addTableFunction(target_sym_index);
2103 return WValue{ .function_index = target_sym_index };
2104 } else return WValue{ .memory = target_sym_index };
2105 },
2106 .elem_ptr => {2123 .elem_ptr => {
2107 const elem_ptr = val.castTag(.elem_ptr).?.data;2124 const elem_ptr = val.castTag(.elem_ptr).?.data;
2108 const index = elem_ptr.index;2125 const index = elem_ptr.index;
...@@ -2114,6 +2131,27 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {...@@ -2114,6 +2131,27 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
2114 .offset = @intCast(u32, offset),2131 .offset = @intCast(u32, offset),
2115 } };2132 } };
2116 },2133 },
2134 .field_ptr => {
2135 const field_ptr = val.castTag(.field_ptr).?.data;
2136 const container = field_ptr.container_ptr;
2137 const parent_ptr = try self.lowerConstant(container, ty);
2138
2139 const offset = switch (container.tag()) {
2140 .decl_ref => blk: {
2141 const decl_ref = container.castTag(.decl_ref).?.data;
2142 if (decl_ref.ty.castTag(.@"struct")) |_| {
2143 const offset = decl_ref.ty.structFieldOffset(field_ptr.field_index, self.target);
2144 break :blk offset;
2145 }
2146 return self.fail("Wasm TODO: field_ptr decl_ref for type '{}'", .{decl_ref.ty});
2147 },
2148 else => |tag| return self.fail("Wasm TODO: Implement field_ptr for value tag: '{s}'", .{tag}),
2149 };
2150 return WValue{ .memory_offset = .{
2151 .pointer = parent_ptr.memory,
2152 .offset = @intCast(u32, offset),
2153 } };
2154 },
2117 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) },2155 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) },
2118 .zero, .null_value => return WValue{ .imm32 = 0 },2156 .zero, .null_value => return WValue{ .imm32 = 0 },
2119 else => return self.fail("Wasm TODO: lowerConstant for other const pointer tag {s}", .{val.tag()}),2157 else => return self.fail("Wasm TODO: lowerConstant for other const pointer tag {s}", .{val.tag()}),
...@@ -2160,7 +2198,14 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {...@@ -2160,7 +2198,14 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
2160 },2198 },
2161 .Optional => if (ty.isPtrLikeOptional()) {2199 .Optional => if (ty.isPtrLikeOptional()) {
2162 var buf: Type.Payload.ElemType = undefined;2200 var buf: Type.Payload.ElemType = undefined;
2163 return self.lowerConstant(val, ty.optionalChild(&buf));2201 const pl_ty = ty.optionalChild(&buf);
2202 if (val.castTag(.opt_payload)) |payload| {
2203 return self.lowerConstant(payload.data, pl_ty);
2204 } else if (val.isNull()) {
2205 return WValue{ .imm32 = 0 };
2206 } else {
2207 return self.lowerConstant(val, pl_ty);
2208 }
2164 } else {2209 } else {
2165 const is_pl = val.tag() == .opt_payload;2210 const is_pl = val.tag() == .opt_payload;
2166 return WValue{ .imm32 = if (is_pl) @as(u32, 1) else 0 };2211 return WValue{ .imm32 = if (is_pl) @as(u32, 1) else 0 };
src/link/Wasm.zig+3-3
...@@ -428,7 +428,7 @@ pub fn addTableFunction(self: *Wasm, symbol_index: u32) !void {...@@ -428,7 +428,7 @@ pub fn addTableFunction(self: *Wasm, symbol_index: u32) !void {
428428
429fn mapFunctionTable(self: *Wasm) void {429fn mapFunctionTable(self: *Wasm) void {
430 var it = self.function_table.valueIterator();430 var it = self.function_table.valueIterator();
431 var index: u32 = 0;431 var index: u32 = 1;
432 while (it.next()) |value_ptr| : (index += 1) {432 while (it.next()) |value_ptr| : (index += 1) {
433 value_ptr.* = index;433 value_ptr.* = index;
434 }434 }
...@@ -821,7 +821,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {...@@ -821,7 +821,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
821821
822 try leb.writeULEB128(writer, wasm.reftype(.funcref));822 try leb.writeULEB128(writer, wasm.reftype(.funcref));
823 try emitLimits(writer, .{823 try emitLimits(writer, .{
824 .min = @intCast(u32, self.function_table.count()),824 .min = @intCast(u32, self.function_table.count()) + 1,
825 .max = null,825 .max = null,
826 });826 });
827827
...@@ -931,7 +931,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {...@@ -931,7 +931,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
931 var flags: u32 = 0x2; // Yes we have a table931 var flags: u32 = 0x2; // Yes we have a table
932 try leb.writeULEB128(writer, flags);932 try leb.writeULEB128(writer, flags);
933 try leb.writeULEB128(writer, @as(u32, 0)); // index of that table. TODO: Store synthetic symbols933 try leb.writeULEB128(writer, @as(u32, 0)); // index of that table. TODO: Store synthetic symbols
934 try emitInit(writer, .{ .i32_const = 0 });934 try emitInit(writer, .{ .i32_const = 1 }); // We start at index 1, so unresolved function pointers are invalid
935 try leb.writeULEB128(writer, @as(u8, 0));935 try leb.writeULEB128(writer, @as(u8, 0));
936 try leb.writeULEB128(writer, @intCast(u32, self.function_table.count()));936 try leb.writeULEB128(writer, @intCast(u32, self.function_table.count()));
937 var symbol_it = self.function_table.keyIterator();937 var symbol_it = self.function_table.keyIterator();
test/behavior.zig+4-4
...@@ -23,6 +23,8 @@ test {...@@ -23,6 +23,8 @@ test {
23 _ = @import("behavior/bugs/1914.zig");23 _ = @import("behavior/bugs/1914.zig");
24 _ = @import("behavior/bugs/2006.zig");24 _ = @import("behavior/bugs/2006.zig");
25 _ = @import("behavior/bugs/2346.zig");25 _ = @import("behavior/bugs/2346.zig");
26 _ = @import("behavior/bugs/2578.zig");
27 _ = @import("behavior/bugs/3007.zig");
26 _ = @import("behavior/bugs/3112.zig");28 _ = @import("behavior/bugs/3112.zig");
27 _ = @import("behavior/bugs/3367.zig");29 _ = @import("behavior/bugs/3367.zig");
28 _ = @import("behavior/bugs/6850.zig");30 _ = @import("behavior/bugs/6850.zig");
...@@ -58,9 +60,11 @@ test {...@@ -58,9 +60,11 @@ test {
58 _ = @import("behavior/bugs/4954.zig");60 _ = @import("behavior/bugs/4954.zig");
59 _ = @import("behavior/byval_arg_var.zig");61 _ = @import("behavior/byval_arg_var.zig");
60 _ = @import("behavior/call.zig");62 _ = @import("behavior/call.zig");
63 _ = @import("behavior/cast_llvm.zig");
61 _ = @import("behavior/defer.zig");64 _ = @import("behavior/defer.zig");
62 _ = @import("behavior/enum.zig");65 _ = @import("behavior/enum.zig");
63 _ = @import("behavior/error.zig");66 _ = @import("behavior/error.zig");
67 _ = @import("behavior/fn.zig");
64 _ = @import("behavior/for.zig");68 _ = @import("behavior/for.zig");
65 _ = @import("behavior/generics.zig");69 _ = @import("behavior/generics.zig");
66 _ = @import("behavior/if.zig");70 _ = @import("behavior/if.zig");
...@@ -93,14 +97,10 @@ test {...@@ -93,14 +97,10 @@ test {
93 if (builtin.zig_backend != .stage2_c) {97 if (builtin.zig_backend != .stage2_c) {
94 // Tests that pass for stage1 and the llvm backend.98 // Tests that pass for stage1 and the llvm backend.
95 _ = @import("behavior/atomics.zig");99 _ = @import("behavior/atomics.zig");
96 _ = @import("behavior/bugs/2578.zig");
97 _ = @import("behavior/bugs/3007.zig");
98 _ = @import("behavior/bugs/9584.zig");100 _ = @import("behavior/bugs/9584.zig");
99 _ = @import("behavior/cast_llvm.zig");
100 _ = @import("behavior/error_llvm.zig");101 _ = @import("behavior/error_llvm.zig");
101 _ = @import("behavior/eval.zig");102 _ = @import("behavior/eval.zig");
102 _ = @import("behavior/floatop.zig");103 _ = @import("behavior/floatop.zig");
103 _ = @import("behavior/fn.zig");
104 _ = @import("behavior/math.zig");104 _ = @import("behavior/math.zig");
105 _ = @import("behavior/maximum_minimum.zig");105 _ = @import("behavior/maximum_minimum.zig");
106 _ = @import("behavior/merge_error_sets.zig");106 _ = @import("behavior/merge_error_sets.zig");
test/behavior/bugs/2578.zig+6
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1const builtin = @import("builtin");
2
1const Foo = struct {3const Foo = struct {
2 y: u8,4 y: u8,
3};5};
...@@ -10,5 +12,9 @@ fn bar(pointer: ?*anyopaque) void {...@@ -10,5 +12,9 @@ fn bar(pointer: ?*anyopaque) void {
10}12}
1113
12test "fixed" {14test "fixed" {
15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
18
13 bar(t);19 bar(t);
14}20}
test/behavior/bugs/3007.zig+5
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");
23
3const Foo = struct {4const Foo = struct {
4 free: bool,5 free: bool,
...@@ -18,6 +19,10 @@ fn get_foo() Foo.FooError!*Foo {...@@ -18,6 +19,10 @@ fn get_foo() Foo.FooError!*Foo {
18}19}
1920
20test "fixed" {21test "fixed" {
22 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
23 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
25
21 default_foo = get_foo() catch null; // This Line26 default_foo = get_foo() catch null; // This Line
22 try std.testing.expect(!default_foo.?.free);27 try std.testing.expect(!default_foo.?.free);
23}28}
test/behavior/cast_llvm.zig+24
...@@ -6,6 +6,8 @@ const maxInt = std.math.maxInt;...@@ -6,6 +6,8 @@ const maxInt = std.math.maxInt;
6const native_endian = builtin.target.cpu.arch.endian();6const native_endian = builtin.target.cpu.arch.endian();
77
8test "pointer reinterpret const float to int" {8test "pointer reinterpret const float to int" {
9 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
10
9 // The hex representation is 0x3fe3333333333303.11 // The hex representation is 0x3fe3333333333303.
10 const float: f64 = 5.99999999999994648725e-01;12 const float: f64 = 5.99999999999994648725e-01;
11 const float_ptr = &float;13 const float_ptr = &float;
...@@ -18,6 +20,8 @@ test "pointer reinterpret const float to int" {...@@ -18,6 +20,8 @@ test "pointer reinterpret const float to int" {
18}20}
1921
20test "@floatToInt" {22test "@floatToInt" {
23 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
24
21 try testFloatToInts();25 try testFloatToInts();
22 comptime try testFloatToInts();26 comptime try testFloatToInts();
23}27}
...@@ -33,6 +37,8 @@ fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void {...@@ -33,6 +37,8 @@ fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void {
33}37}
3438
35test "implicit cast from [*]T to ?*anyopaque" {39test "implicit cast from [*]T to ?*anyopaque" {
40 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
41
36 var a = [_]u8{ 3, 2, 1 };42 var a = [_]u8{ 3, 2, 1 };
37 var runtime_zero: usize = 0;43 var runtime_zero: usize = 0;
38 incrementVoidPtrArray(a[runtime_zero..].ptr, 3);44 incrementVoidPtrArray(a[runtime_zero..].ptr, 3);
...@@ -49,6 +55,7 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {...@@ -49,6 +55,7 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {
49test "compile time int to ptr of function" {55test "compile time int to ptr of function" {
50 if (builtin.zig_backend == .stage1) return error.SkipZigTest;56 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
51 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO57 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
5259
53 try foobar(FUNCTION_CONSTANT);60 try foobar(FUNCTION_CONSTANT);
54}61}
...@@ -61,6 +68,8 @@ fn foobar(func: PFN_void) !void {...@@ -61,6 +68,8 @@ fn foobar(func: PFN_void) !void {
61}68}
6269
63test "implicit ptr to *anyopaque" {70test "implicit ptr to *anyopaque" {
71 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
72
64 var a: u32 = 1;73 var a: u32 = 1;
65 var ptr: *align(@alignOf(u32)) anyopaque = &a;74 var ptr: *align(@alignOf(u32)) anyopaque = &a;
66 var b: *u32 = @ptrCast(*u32, ptr);75 var b: *u32 = @ptrCast(*u32, ptr);
...@@ -87,6 +96,7 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {...@@ -87,6 +96,7 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {
87}96}
8897
89test "peer type resolution: [0]u8 and []const u8" {98test "peer type resolution: [0]u8 and []const u8" {
99 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
90 try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);100 try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
91 try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);101 try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
92 comptime {102 comptime {
...@@ -103,6 +113,7 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {...@@ -103,6 +113,7 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
103}113}
104114
105test "implicitly cast from [N]T to ?[]const T" {115test "implicitly cast from [N]T to ?[]const T" {
116 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
106 try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));117 try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
107 comptime try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));118 comptime try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
108}119}
...@@ -112,6 +123,7 @@ fn castToOptionalSlice() ?[]const u8 {...@@ -112,6 +123,7 @@ fn castToOptionalSlice() ?[]const u8 {
112}123}
113124
114test "cast u128 to f128 and back" {125test "cast u128 to f128 and back" {
126 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
115 comptime try testCast128();127 comptime try testCast128();
116 try testCast128();128 try testCast128();
117}129}
...@@ -129,6 +141,7 @@ fn cast128Float(x: u128) f128 {...@@ -129,6 +141,7 @@ fn cast128Float(x: u128) f128 {
129}141}
130142
131test "implicit cast from *[N]T to ?[*]T" {143test "implicit cast from *[N]T to ?[*]T" {
144 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
132 var x: ?[*]u16 = null;145 var x: ?[*]u16 = null;
133 var y: [4]u16 = [4]u16{ 0, 1, 2, 3 };146 var y: [4]u16 = [4]u16{ 0, 1, 2, 3 };
134147
...@@ -140,6 +153,7 @@ test "implicit cast from *[N]T to ?[*]T" {...@@ -140,6 +153,7 @@ test "implicit cast from *[N]T to ?[*]T" {
140}153}
141154
142test "implicit cast from *T to ?*anyopaque" {155test "implicit cast from *T to ?*anyopaque" {
156 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
143 var a: u8 = 1;157 var a: u8 = 1;
144 incrementVoidPtrValue(&a);158 incrementVoidPtrValue(&a);
145 try std.testing.expect(a == 2);159 try std.testing.expect(a == 2);
...@@ -150,6 +164,7 @@ fn incrementVoidPtrValue(value: ?*anyopaque) void {...@@ -150,6 +164,7 @@ fn incrementVoidPtrValue(value: ?*anyopaque) void {
150}164}
151165
152test "implicit cast *[0]T to E![]const u8" {166test "implicit cast *[0]T to E![]const u8" {
167 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
153 var x = @as(anyerror![]const u8, &[0]u8{});168 var x = @as(anyerror![]const u8, &[0]u8{});
154 try expect((x catch unreachable).len == 0);169 try expect((x catch unreachable).len == 0);
155}170}
...@@ -160,11 +175,13 @@ test "cast from array reference to fn: comptime fn ptr" {...@@ -160,11 +175,13 @@ test "cast from array reference to fn: comptime fn ptr" {
160 try expect(@ptrToInt(f) == @ptrToInt(&global_array));175 try expect(@ptrToInt(f) == @ptrToInt(&global_array));
161}176}
162test "cast from array reference to fn: runtime fn ptr" {177test "cast from array reference to fn: runtime fn ptr" {
178 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
163 var f = @ptrCast(*const fn () callconv(.C) void, &global_array);179 var f = @ptrCast(*const fn () callconv(.C) void, &global_array);
164 try expect(@ptrToInt(f) == @ptrToInt(&global_array));180 try expect(@ptrToInt(f) == @ptrToInt(&global_array));
165}181}
166182
167test "*const [N]null u8 to ?[]const u8" {183test "*const [N]null u8 to ?[]const u8" {
184 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
168 const S = struct {185 const S = struct {
169 fn doTheTest() !void {186 fn doTheTest() !void {
170 var a = "Hello";187 var a = "Hello";
...@@ -196,6 +213,7 @@ test "cast between [*c]T and ?[*:0]T on fn parameter" {...@@ -196,6 +213,7 @@ test "cast between [*c]T and ?[*:0]T on fn parameter" {
196213
197var global_struct: struct { f0: usize } = undefined;214var global_struct: struct { f0: usize } = undefined;
198test "assignment to optional pointer result loc" {215test "assignment to optional pointer result loc" {
216 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
199 var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct };217 var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct };
200 try expect(foo.ptr.? == @ptrCast(*anyopaque, &global_struct));218 try expect(foo.ptr.? == @ptrCast(*anyopaque, &global_struct));
201}219}
...@@ -217,6 +235,8 @@ fn boolToStr(b: bool) []const u8 {...@@ -217,6 +235,8 @@ fn boolToStr(b: bool) []const u8 {
217}235}
218236
219test "cast f16 to wider types" {237test "cast f16 to wider types" {
238 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
239 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
220 const S = struct {240 const S = struct {
221 fn doTheTest() !void {241 fn doTheTest() !void {
222 var x: f16 = 1234.0;242 var x: f16 = 1234.0;
...@@ -230,6 +250,9 @@ test "cast f16 to wider types" {...@@ -230,6 +250,9 @@ test "cast f16 to wider types" {
230}250}
231251
232test "cast f128 to narrower types" {252test "cast f128 to narrower types" {
253 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
254 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
255
233 const S = struct {256 const S = struct {
234 fn doTheTest() !void {257 fn doTheTest() !void {
235 var x: f128 = 1234.0;258 var x: f128 = 1234.0;
...@@ -243,6 +266,7 @@ test "cast f128 to narrower types" {...@@ -243,6 +266,7 @@ test "cast f128 to narrower types" {
243}266}
244267
245test "peer type resolution: unreachable, null, slice" {268test "peer type resolution: unreachable, null, slice" {
269 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
246 const S = struct {270 const S = struct {
247 fn doTheTest(num: usize, word: []const u8) !void {271 fn doTheTest(num: usize, word: []const u8) !void {
248 const result = switch (num) {272 const result = switch (num) {
test/behavior/fn.zig+5
...@@ -75,6 +75,7 @@ test "return inner function which references comptime variable of outer function...@@ -75,6 +75,7 @@ test "return inner function which references comptime variable of outer function
75}75}
7676
77test "discard the result of a function that returns a struct" {77test "discard the result of a function that returns a struct" {
78 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
78 const S = struct {79 const S = struct {
79 fn entry() void {80 fn entry() void {
80 _ = func();81 _ = func();
...@@ -94,6 +95,7 @@ test "discard the result of a function that returns a struct" {...@@ -94,6 +95,7 @@ test "discard the result of a function that returns a struct" {
94}95}
9596
96test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" {97test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" {
98 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
97 if (builtin.zig_backend == .stage1) return error.SkipZigTest;99 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
98100
99 const S = struct {101 const S = struct {
...@@ -139,6 +141,7 @@ fn fnWithUnreachable() noreturn {...@@ -139,6 +141,7 @@ fn fnWithUnreachable() noreturn {
139}141}
140142
141test "extern struct with stdcallcc fn pointer" {143test "extern struct with stdcallcc fn pointer" {
144 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
142 if (builtin.zig_backend == .stage1) return error.SkipZigTest;145 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
143146
144 const S = extern struct {147 const S = extern struct {
...@@ -252,6 +255,7 @@ test "implicit cast fn call result to optional in field result" {...@@ -252,6 +255,7 @@ test "implicit cast fn call result to optional in field result" {
252}255}
253256
254test "void parameters" {257test "void parameters" {
258 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
255 try voidFun(1, void{}, 2, {});259 try voidFun(1, void{}, 2, {});
256}260}
257fn voidFun(a: i32, b: void, c: i32, d: void) !void {261fn voidFun(a: i32, b: void, c: i32, d: void) !void {
...@@ -306,6 +310,7 @@ fn numberLiteralArg(a: anytype) !void {...@@ -306,6 +310,7 @@ fn numberLiteralArg(a: anytype) !void {
306}310}
307311
308test "function call with anon list literal" {312test "function call with anon list literal" {
313 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
309 const S = struct {314 const S = struct {
310 fn doTheTest() !void {315 fn doTheTest() !void {
311 try consumeVec(.{ 9, 8, 7 });316 try consumeVec(.{ 9, 8, 7 });