authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-02 17:28:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-02 17:28:39-07:00
log1c8a86f063b65e95c2e23ceaa40843069adfdc23
tree2ff8a2b231a4e3cc5f21f5681f7b092c0ddc3bb9
parent220708e7c3f437958fbf8376975b70542b9ac199

Sema: detect comptime-known union initializations

Follow a similar pattern as we already do for validate_array_init and validate_struct_init. I threw in a bit of behavior test cleanup on top of it.

9 files changed, 340 insertions(+), 78 deletions(-)

src/Sema.zig+123-39
...@@ -2737,6 +2737,7 @@ fn zirValidateStructInit(...@@ -2737,6 +2737,7 @@ fn zirValidateStructInit(
2737 init_src,2737 init_src,
2738 instrs,2738 instrs,
2739 object_ptr,2739 object_ptr,
2740 is_comptime,
2740 ),2741 ),
2741 else => unreachable,2742 else => unreachable,
2742 }2743 }
...@@ -2749,6 +2750,7 @@ fn validateUnionInit(...@@ -2749,6 +2750,7 @@ fn validateUnionInit(
2749 init_src: LazySrcLoc,2750 init_src: LazySrcLoc,
2750 instrs: []const Zir.Inst.Index,2751 instrs: []const Zir.Inst.Index,
2751 union_ptr: Air.Inst.Ref,2752 union_ptr: Air.Inst.Ref,
2753 is_comptime: bool,
2752) CompileError!void {2754) CompileError!void {
2753 if (instrs.len != 1) {2755 if (instrs.len != 1) {
2754 const msg = msg: {2756 const msg = msg: {
...@@ -2771,6 +2773,11 @@ fn validateUnionInit(...@@ -2771,6 +2773,11 @@ fn validateUnionInit(
2771 return sema.failWithOwnedErrorMsg(msg);2773 return sema.failWithOwnedErrorMsg(msg);
2772 }2774 }
27732775
2776 if (is_comptime or block.is_comptime) {
2777 // In this case, comptime machinery already did everything. No work to do here.
2778 return;
2779 }
2780
2774 const field_ptr = instrs[0];2781 const field_ptr = instrs[0];
2775 const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node;2782 const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node;
2776 const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_ptr_data.src_node };2783 const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_ptr_data.src_node };
...@@ -2779,44 +2786,72 @@ fn validateUnionInit(...@@ -2779,44 +2786,72 @@ fn validateUnionInit(
2779 const field_index_big = union_obj.fields.getIndex(field_name) orelse2786 const field_index_big = union_obj.fields.getIndex(field_name) orelse
2780 return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);2787 return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);
2781 const field_index = @intCast(u32, field_index_big);2788 const field_index = @intCast(u32, field_index_big);
27822789 const air_tags = sema.air_instructions.items(.tag);
2783 // Handle the possibility of the union value being comptime-known.2790 const air_datas = sema.air_instructions.items(.data);
2784 const union_ptr_inst = Air.refToIndex(union_ptr).?;2791 const field_ptr_air_ref = sema.inst_map.get(field_ptr).?;
2785 switch (sema.air_instructions.items(.tag)[union_ptr_inst]) {2792 const field_ptr_air_inst = Air.refToIndex(field_ptr_air_ref).?;
2786 .constant => {2793
2787 if (try sema.resolveDefinedValue(block, init_src, union_ptr)) |ptr_val| {2794 // Our task here is to determine if the union is comptime-known. In such case,
2788 if (ptr_val.isComptimeMutablePtr()) {2795 // we erase the runtime AIR instructions for initializing the union, and replace
2789 // In this case the tag has already been set. No validation to do.2796 // the mapping with the comptime value. Either way, we will need to populate the tag.
2790 return;2797
2791 }2798 // We expect to see something like this in the current block AIR:
2792 }2799 // %a = alloc(*const U)
2793 },2800 // %b = bitcast(*U, %a)
2794 .bitcast => {2801 // %c = field_ptr(..., %b)
2795 // TODO here we need to go back and see if we need to convert the union2802 // %e!= store(%c!, %d!)
2796 // to a comptime-known value. In such case, we must delete all the instructions2803 // If %d is a comptime operand, the union is comptime.
2797 // added to the current block starting with the bitcast.2804 // If the union is comptime, we want `first_block_index`
2798 // If the bitcast result ptr is an alloc, the alloc should be replaced with2805 // to point at %c so that the bitcast becomes the last instruction in the block.
2799 // a constant decl_ref.2806 //
2800 // Otherwise, the bitcast should be preserved and a store instruction should be2807 // In the case of a comptime-known pointer to a union, the
2801 // emitted to store the constant union value through the bitcast.2808 // the field_ptr instruction is missing, so we have to pattern-match
2802 },2809 // based only on the store instructions.
2803 .alloc => {},2810 // `first_block_index` needs to point to the `field_ptr` if it exists;
2804 else => |t| {2811 // the `store` otherwise.
2805 if (std.debug.runtime_safety) {2812 //
2806 std.debug.panic("unexpected AIR tag for union pointer: {s}", .{@tagName(t)});2813 // It's also possible for there to be no store instruction, in the case
2807 } else {2814 // of nested `coerce_result_ptr` instructions. If we see the `field_ptr`
2808 unreachable;2815 // but we have not found a `store`, treat as a runtime-known field.
2809 }2816 var first_block_index = block.instructions.items.len;
2810 },2817 var block_index = block.instructions.items.len - 1;
2818 var init_val: ?Value = null;
2819 while (block_index > 0) : (block_index -= 1) {
2820 const store_inst = block.instructions.items[block_index];
2821 if (store_inst == field_ptr_air_inst) break;
2822 if (air_tags[store_inst] != .store) continue;
2823 const bin_op = air_datas[store_inst].bin_op;
2824 if (bin_op.lhs != field_ptr_air_ref) continue;
2825 if (block_index > 0 and
2826 field_ptr_air_inst == block.instructions.items[block_index - 1])
2827 {
2828 first_block_index = @minimum(first_block_index, block_index - 1);
2829 } else {
2830 first_block_index = @minimum(first_block_index, block_index);
2831 }
2832 init_val = try sema.resolveMaybeUndefValAllowVariables(block, init_src, bin_op.rhs);
2833 break;
2811 }2834 }
28122835
2813 // Otherwise, we set the new union tag now.2836 const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index);
2814 const new_tag = try sema.addConstant(2837
2815 union_obj.tag_ty,2838 if (init_val) |val| {
2816 try Value.Tag.enum_field_index.create(sema.arena, field_index),2839 // Our task is to delete all the `field_ptr` and `store` instructions, and insert
2817 );2840 // instead a single `store` to the result ptr with a comptime union value.
2841 block.instructions.shrinkRetainingCapacity(first_block_index);
2842
2843 const union_val = try Value.Tag.@"union".create(sema.arena, .{
2844 .tag = tag_val,
2845 .val = val,
2846 });
2847 const union_ty = sema.typeOf(union_ptr).childType();
2848 const union_init = try sema.addConstant(union_ty, union_val);
2849 try sema.storePtr2(block, init_src, union_ptr, init_src, union_init, init_src, .store);
2850 return;
2851 }
28182852
2819 try sema.requireRuntimeBlock(block, init_src);2853 try sema.requireRuntimeBlock(block, init_src);
2854 const new_tag = try sema.addConstant(union_obj.tag_ty, tag_val);
2820 _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag);2855 _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag);
2821}2856}
28222857
...@@ -3084,7 +3119,7 @@ fn zirValidateArrayInit(...@@ -3084,7 +3119,7 @@ fn zirValidateArrayInit(
3084 }3119 }
30853120
3086 var array_is_comptime = true;3121 var array_is_comptime = true;
3087 var first_block_index: usize = std.math.maxInt(u32);3122 var first_block_index = block.instructions.items.len;
30883123
3089 // Collect the comptime element values in case the array literal ends up3124 // Collect the comptime element values in case the array literal ends up
3090 // being comptime-known.3125 // being comptime-known.
...@@ -15147,7 +15182,32 @@ fn unionFieldPtr(...@@ -15147,7 +15182,32 @@ fn unionFieldPtr(
15147 });15182 });
1514815183
15149 if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| {15184 if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| {
15150 // TODO detect inactive union field and emit compile error15185 switch (union_obj.layout) {
15186 .Auto => {
15187 // TODO emit the access of inactive union field error commented out below.
15188 // In order to do that, we need to first solve the problem that AstGen
15189 // emits field_ptr instructions in order to initialize union values.
15190 // In such case we need to know that the field_ptr instruction (which is
15191 // calling this unionFieldPtr function) is *initializing* the union,
15192 // in which case we would skip this check, and in fact we would actually
15193 // set the union tag here and the payload to undefined.
15194
15195 //const tag_and_val = union_val.castTag(.@"union").?.data;
15196 //var field_tag_buf: Value.Payload.U32 = .{
15197 // .base = .{ .tag = .enum_field_index },
15198 // .data = field_index,
15199 //};
15200 //const field_tag = Value.initPayload(&field_tag_buf.base);
15201 //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);
15202 //if (!tag_matches) {
15203 // // TODO enhance this saying which one was active
15204 // // and which one was accessed, and showing where the union was declared.
15205 // return sema.fail(block, src, "access of inactive union field", .{});
15206 //}
15207 // TODO add runtime safety check for the active tag
15208 },
15209 .Packed, .Extern => {},
15210 }
15151 return sema.addConstant(15211 return sema.addConstant(
15152 ptr_field_ty,15212 ptr_field_ty,
15153 try Value.Tag.field_ptr.create(arena, .{15213 try Value.Tag.field_ptr.create(arena, .{
...@@ -15183,9 +15243,33 @@ fn unionFieldVal(...@@ -15183,9 +15243,33 @@ fn unionFieldVal(
15183 if (try sema.resolveMaybeUndefVal(block, src, union_byval)) |union_val| {15243 if (try sema.resolveMaybeUndefVal(block, src, union_byval)) |union_val| {
15184 if (union_val.isUndef()) return sema.addConstUndef(field.ty);15244 if (union_val.isUndef()) return sema.addConstUndef(field.ty);
1518515245
15186 // TODO detect inactive union field and emit compile error15246 const tag_and_val = union_val.castTag(.@"union").?.data;
15187 const active_val = union_val.castTag(.@"union").?.data.val;15247 var field_tag_buf: Value.Payload.U32 = .{
15188 return sema.addConstant(field.ty, active_val);15248 .base = .{ .tag = .enum_field_index },
15249 .data = field_index,
15250 };
15251 const field_tag = Value.initPayload(&field_tag_buf.base);
15252 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);
15253 switch (union_obj.layout) {
15254 .Auto => {
15255 if (tag_matches) {
15256 return sema.addConstant(field.ty, tag_and_val.val);
15257 } else {
15258 // TODO enhance this saying which one was active
15259 // and which one was accessed, and showing where the union was declared.
15260 return sema.fail(block, src, "access of inactive union field", .{});
15261 }
15262 },
15263 .Packed, .Extern => {
15264 if (tag_matches) {
15265 return sema.addConstant(field.ty, tag_and_val.val);
15266 } else {
15267 const old_ty = union_ty.unionFieldType(tag_and_val.tag);
15268 const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty);
15269 return sema.addConstant(field.ty, new_val);
15270 }
15271 },
15272 }
15189 }15273 }
1519015274
15191 try sema.requireRuntimeBlock(block, src);15275 try sema.requireRuntimeBlock(block, src);
test/behavior.zig+2-3
...@@ -51,6 +51,7 @@ test {...@@ -51,6 +51,7 @@ test {
51 _ = @import("behavior/defer.zig");51 _ = @import("behavior/defer.zig");
52 _ = @import("behavior/enum.zig");52 _ = @import("behavior/enum.zig");
53 _ = @import("behavior/error.zig");53 _ = @import("behavior/error.zig");
54 _ = @import("behavior/floatop.zig");
54 _ = @import("behavior/fn.zig");55 _ = @import("behavior/fn.zig");
55 _ = @import("behavior/fn_delegation.zig");56 _ = @import("behavior/fn_delegation.zig");
56 _ = @import("behavior/fn_in_struct_in_comptime.zig");57 _ = @import("behavior/fn_in_struct_in_comptime.zig");
...@@ -79,6 +80,7 @@ test {...@@ -79,6 +80,7 @@ test {
79 _ = @import("behavior/slice_sentinel_comptime.zig");80 _ = @import("behavior/slice_sentinel_comptime.zig");
80 _ = @import("behavior/src.zig");81 _ = @import("behavior/src.zig");
81 _ = @import("behavior/struct.zig");82 _ = @import("behavior/struct.zig");
83 _ = @import("behavior/switch.zig");
82 _ = @import("behavior/this.zig");84 _ = @import("behavior/this.zig");
83 _ = @import("behavior/truncate.zig");85 _ = @import("behavior/truncate.zig");
84 _ = @import("behavior/try.zig");86 _ = @import("behavior/try.zig");
...@@ -93,7 +95,6 @@ test {...@@ -93,7 +95,6 @@ test {
93 _ = @import("behavior/void.zig");95 _ = @import("behavior/void.zig");
94 _ = @import("behavior/while.zig");96 _ = @import("behavior/while.zig");
9597
96 // tests that don't pass for stage1
97 if (builtin.zig_backend != .stage1) {98 if (builtin.zig_backend != .stage1) {
98 _ = @import("behavior/decltest.zig");99 _ = @import("behavior/decltest.zig");
99 }100 }
...@@ -116,13 +117,11 @@ test {...@@ -116,13 +117,11 @@ test {
116 if (builtin.zig_backend != .stage2_c) {117 if (builtin.zig_backend != .stage2_c) {
117 // Tests that pass for stage1 and the llvm backend.118 // Tests that pass for stage1 and the llvm backend.
118 _ = @import("behavior/atomics.zig");119 _ = @import("behavior/atomics.zig");
119 _ = @import("behavior/floatop.zig");
120 _ = @import("behavior/math.zig");120 _ = @import("behavior/math.zig");
121 _ = @import("behavior/maximum_minimum.zig");121 _ = @import("behavior/maximum_minimum.zig");
122 _ = @import("behavior/popcount.zig");122 _ = @import("behavior/popcount.zig");
123 _ = @import("behavior/saturating_arithmetic.zig");123 _ = @import("behavior/saturating_arithmetic.zig");
124 _ = @import("behavior/sizeof_and_typeof.zig");124 _ = @import("behavior/sizeof_and_typeof.zig");
125 _ = @import("behavior/switch.zig");
126 _ = @import("behavior/widening.zig");125 _ = @import("behavior/widening.zig");
127 _ = @import("behavior/bugs/421.zig");126 _ = @import("behavior/bugs/421.zig");
128 _ = @import("behavior/bugs/726.zig");127 _ = @import("behavior/bugs/726.zig");
test/behavior/array.zig+7-3
...@@ -108,15 +108,19 @@ test "array len field" {...@@ -108,15 +108,19 @@ test "array len field" {
108}108}
109109
110test "array with sentinels" {110test "array with sentinels" {
111 if (builtin.zig_backend == .stage1) {
112 // Stage1 test coverage disabled at runtime because of
113 // https://github.com/ziglang/zig/issues/4372
114 return error.SkipZigTest;
115 }
116
111 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;117 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
112 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;118 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
113119
114 const S = struct {120 const S = struct {
115 fn doTheTest(is_ct: bool) !void {121 fn doTheTest(is_ct: bool) !void {
116 if (is_ct or builtin.zig_backend != .stage1) {122 {
117 var zero_sized: [0:0xde]u8 = [_:0xde]u8{};123 var zero_sized: [0:0xde]u8 = [_:0xde]u8{};
118 // Stage1 test coverage disabled at runtime because of
119 // https://github.com/ziglang/zig/issues/4372
120 try expect(zero_sized[0] == 0xde);124 try expect(zero_sized[0] == 0xde);
121 var reinterpreted = @ptrCast(*[1]u8, &zero_sized);125 var reinterpreted = @ptrCast(*[1]u8, &zero_sized);
122 try expect(reinterpreted[0] == 0xde);126 try expect(reinterpreted[0] == 0xde);
test/behavior/cast.zig+6-4
...@@ -1050,9 +1050,9 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {...@@ -1050,9 +1050,9 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {
1050}1050}
10511051
1052test "compile time int to ptr of function" {1052test "compile time int to ptr of function" {
1053 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1054 if (builtin.zig_backend == .stage1) return error.SkipZigTest;1053 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1055 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO1054
1055 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1056 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO1056 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1057 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1057 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1058 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1058 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
...@@ -1060,11 +1060,13 @@ test "compile time int to ptr of function" {...@@ -1060,11 +1060,13 @@ test "compile time int to ptr of function" {
1060 try foobar(FUNCTION_CONSTANT);1060 try foobar(FUNCTION_CONSTANT);
1061}1061}
10621062
1063pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize));1063// On some architectures function pointers must be aligned.
1064const hardcoded_fn_addr = maxInt(usize) & ~@as(usize, 0xf);
1065pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, hardcoded_fn_addr);
1064pub const PFN_void = *const fn (*anyopaque) callconv(.C) void;1066pub const PFN_void = *const fn (*anyopaque) callconv(.C) void;
10651067
1066fn foobar(func: PFN_void) !void {1068fn foobar(func: PFN_void) !void {
1067 try std.testing.expect(@ptrToInt(func) == maxInt(usize));1069 try std.testing.expect(@ptrToInt(func) == hardcoded_fn_addr);
1068}1070}
10691071
1070test "implicit ptr to *anyopaque" {1072test "implicit ptr to *anyopaque" {
test/behavior/floatop.zig+94-10
...@@ -21,6 +21,12 @@ fn epsForType(comptime T: type) T {...@@ -21,6 +21,12 @@ fn epsForType(comptime T: type) T {
21}21}
2222
23test "floating point comparisons" {23test "floating point comparisons" {
24 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
26 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
27 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
28 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
29
24 try testFloatComparisons();30 try testFloatComparisons();
25 comptime try testFloatComparisons();31 comptime try testFloatComparisons();
26}32}
...@@ -51,6 +57,12 @@ fn testFloatComparisons() !void {...@@ -51,6 +57,12 @@ fn testFloatComparisons() !void {
51}57}
5258
53test "different sized float comparisons" {59test "different sized float comparisons" {
60 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
61 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
62 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
63 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
64 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
65
54 try testDifferentSizedFloatComparisons();66 try testDifferentSizedFloatComparisons();
55 comptime try testDifferentSizedFloatComparisons();67 comptime try testDifferentSizedFloatComparisons();
56}68}
...@@ -81,12 +93,24 @@ fn testDifferentSizedFloatComparisons() !void {...@@ -81,12 +93,24 @@ fn testDifferentSizedFloatComparisons() !void {
81//}93//}
8294
83test "negative f128 floatToInt at compile-time" {95test "negative f128 floatToInt at compile-time" {
96 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
97 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
98 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
99 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
100 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
101
84 const a: f128 = -2;102 const a: f128 = -2;
85 var b = @floatToInt(i64, a);103 var b = @floatToInt(i64, a);
86 try expect(@as(i64, -2) == b);104 try expect(@as(i64, -2) == b);
87}105}
88106
89test "@sqrt" {107test "@sqrt" {
108 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
110 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
111 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
112 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
113
90 comptime try testSqrt();114 comptime try testSqrt();
91 try testSqrt();115 try testSqrt();
92}116}
...@@ -129,6 +153,12 @@ fn testSqrt() !void {...@@ -129,6 +153,12 @@ fn testSqrt() !void {
129}153}
130154
131test "more @sqrt f16 tests" {155test "more @sqrt f16 tests" {
156 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
157 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
158 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
159 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
160 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
161
132 // TODO these are not all passing at comptime162 // TODO these are not all passing at comptime
133 try expect(@sqrt(@as(f16, 0.0)) == 0.0);163 try expect(@sqrt(@as(f16, 0.0)) == 0.0);
134 try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon));164 try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon));
...@@ -149,14 +179,21 @@ test "more @sqrt f16 tests" {...@@ -149,14 +179,21 @@ test "more @sqrt f16 tests" {
149}179}
150180
151test "@sin" {181test "@sin" {
182 if (builtin.zig_backend == .stage1) {
183 // stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)`
184 return error.SkipZigTest;
185 }
186 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
187 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
188 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
189 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
190 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
191
152 comptime try testSin();192 comptime try testSin();
153 try testSin();193 try testSin();
154}194}
155195
156fn testSin() !void {196fn testSin() !void {
157 // stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)`
158 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
159
160 inline for ([_]type{ f16, f32, f64 }) |ty| {197 inline for ([_]type{ f16, f32, f64 }) |ty| {
161 const eps = epsForType(ty);198 const eps = epsForType(ty);
162 try expect(@sin(@as(ty, 0)) == 0);199 try expect(@sin(@as(ty, 0)) == 0);
...@@ -176,14 +213,21 @@ fn testSin() !void {...@@ -176,14 +213,21 @@ fn testSin() !void {
176}213}
177214
178test "@cos" {215test "@cos" {
216 if (builtin.zig_backend == .stage1) {
217 // stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)`
218 return error.SkipZigTest;
219 }
220 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
221 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
222 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
223 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
224 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
225
179 comptime try testCos();226 comptime try testCos();
180 try testCos();227 try testCos();
181}228}
182229
183fn testCos() !void {230fn testCos() !void {
184 // stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)`
185 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
186
187 inline for ([_]type{ f16, f32, f64 }) |ty| {231 inline for ([_]type{ f16, f32, f64 }) |ty| {
188 const eps = epsForType(ty);232 const eps = epsForType(ty);
189 try expect(@cos(@as(ty, 0)) == 1);233 try expect(@cos(@as(ty, 0)) == 1);
...@@ -203,6 +247,12 @@ fn testCos() !void {...@@ -203,6 +247,12 @@ fn testCos() !void {
203}247}
204248
205test "@exp" {249test "@exp" {
250 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
251 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
252 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
253 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
254 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
255
206 comptime try testExp();256 comptime try testExp();
207 try testExp();257 try testExp();
208}258}
...@@ -226,6 +276,12 @@ fn testExp() !void {...@@ -226,6 +276,12 @@ fn testExp() !void {
226}276}
227277
228test "@exp2" {278test "@exp2" {
279 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
280 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
281 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
282 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
283 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
284
229 comptime try testExp2();285 comptime try testExp2();
230 try testExp2();286 try testExp2();
231}287}
...@@ -249,7 +305,7 @@ fn testExp2() !void {...@@ -249,7 +305,7 @@ fn testExp2() !void {
249}305}
250306
251test "@log" {307test "@log" {
252 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO308 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
253309
254 comptime try testLog();310 comptime try testLog();
255 try testLog();311 try testLog();
...@@ -285,7 +341,7 @@ fn testLog() !void {...@@ -285,7 +341,7 @@ fn testLog() !void {
285}341}
286342
287test "@log2" {343test "@log2" {
288 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO344 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
289345
290 comptime try testLog2();346 comptime try testLog2();
291 try testLog2();347 try testLog2();
...@@ -310,7 +366,7 @@ fn testLog2() !void {...@@ -310,7 +366,7 @@ fn testLog2() !void {
310}366}
311367
312test "@log10" {368test "@log10" {
313 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO369 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
314370
315 comptime try testLog10();371 comptime try testLog10();
316 try testLog10();372 try testLog10();
...@@ -335,6 +391,12 @@ fn testLog10() !void {...@@ -335,6 +391,12 @@ fn testLog10() !void {
335}391}
336392
337test "@fabs" {393test "@fabs" {
394 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
395 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
396 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
397 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
398 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
399
338 comptime try testFabs();400 comptime try testFabs();
339 try testFabs();401 try testFabs();
340}402}
...@@ -367,6 +429,12 @@ fn testFabs() !void {...@@ -367,6 +429,12 @@ fn testFabs() !void {
367}429}
368430
369test "@floor" {431test "@floor" {
432 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
433 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
434 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
435 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
436 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
437
370 comptime try testFloor();438 comptime try testFloor();
371 try testFloor();439 try testFloor();
372}440}
...@@ -394,6 +462,12 @@ fn testFloor() !void {...@@ -394,6 +462,12 @@ fn testFloor() !void {
394}462}
395463
396test "@ceil" {464test "@ceil" {
465 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
466 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
467 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
468 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
469 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
470
397 comptime try testCeil();471 comptime try testCeil();
398 try testCeil();472 try testCeil();
399}473}
...@@ -421,6 +495,12 @@ fn testCeil() !void {...@@ -421,6 +495,12 @@ fn testCeil() !void {
421}495}
422496
423test "@trunc" {497test "@trunc" {
498 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
499 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
500 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
501 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
502 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
503
424 comptime try testTrunc();504 comptime try testTrunc();
425 try testTrunc();505 try testTrunc();
426}506}
...@@ -449,7 +529,11 @@ fn testTrunc() !void {...@@ -449,7 +529,11 @@ fn testTrunc() !void {
449529
450test "negation" {530test "negation" {
451 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO531 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
452 if (builtin.os.tag == .freebsd) return error.SkipZigTest;532
533 if (builtin.os.tag == .freebsd) {
534 // TODO file issue to track this failure
535 return error.SkipZigTest;
536 }
453537
454 const S = struct {538 const S = struct {
455 fn doTheTest() !void {539 fn doTheTest() !void {
test/behavior/inttoptr.zig+1-2
...@@ -2,7 +2,6 @@ const builtin = @import("builtin");...@@ -2,7 +2,6 @@ const builtin = @import("builtin");
22
3test "casting integer address to function pointer" {3test "casting integer address to function pointer" {
4 if (builtin.zig_backend == .stage1) return error.SkipZigTest;4 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
5 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO
6 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;5 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
87
...@@ -11,7 +10,7 @@ test "casting integer address to function pointer" {...@@ -11,7 +10,7 @@ test "casting integer address to function pointer" {
11}10}
1211
13fn addressToFunction() void {12fn addressToFunction() void {
14 var addr: usize = 0xdeadbeef;13 var addr: usize = 0xdeadbee0;
15 _ = @intToPtr(*const fn () void, addr);14 _ = @intToPtr(*const fn () void, addr);
16}15}
1716
test/behavior/struct.zig+20-4
...@@ -1175,7 +1175,11 @@ test "for loop over pointers to struct, getting field from struct pointer" {...@@ -1175,7 +1175,11 @@ test "for loop over pointers to struct, getting field from struct pointer" {
11751175
1176test "anon init through error unions and optionals" {1176test "anon init through error unions and optionals" {
1177 if (builtin.zig_backend == .stage1) return error.SkipZigTest;1177 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1178 if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO1178 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1179 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1180 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1181 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1182 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11791183
1180 const S = struct {1184 const S = struct {
1181 a: u32,1185 a: u32,
...@@ -1200,7 +1204,11 @@ test "anon init through error unions and optionals" {...@@ -1200,7 +1204,11 @@ test "anon init through error unions and optionals" {
12001204
1201test "anon init through optional" {1205test "anon init through optional" {
1202 if (builtin.zig_backend == .stage1) return error.SkipZigTest;1206 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1203 if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO1207 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1208 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1209 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1210 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1211 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12041212
1205 const S = struct {1213 const S = struct {
1206 a: u32,1214 a: u32,
...@@ -1218,7 +1226,11 @@ test "anon init through optional" {...@@ -1218,7 +1226,11 @@ test "anon init through optional" {
12181226
1219test "anon init through error union" {1227test "anon init through error union" {
1220 if (builtin.zig_backend == .stage1) return error.SkipZigTest;1228 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1221 if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO1229 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1230 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1231 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1232 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1233 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12221234
1223 const S = struct {1235 const S = struct {
1224 a: u32,1236 a: u32,
...@@ -1236,7 +1248,11 @@ test "anon init through error union" {...@@ -1236,7 +1248,11 @@ test "anon init through error union" {
12361248
1237test "typed init through error unions and optionals" {1249test "typed init through error unions and optionals" {
1238 if (builtin.zig_backend == .stage1) return error.SkipZigTest;1250 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1239 if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO1251 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1252 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1253 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1254 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1255 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12401256
1241 const S = struct {1257 const S = struct {
1242 a: u32,1258 a: u32,
test/behavior/switch.zig+80-6
...@@ -1,9 +1,13 @@...@@ -1,9 +1,13 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const expect = std.testing.expect;3const expect = std.testing.expect;
3const expectError = std.testing.expectError;4const expectError = std.testing.expectError;
4const expectEqual = std.testing.expectEqual;5const expectEqual = std.testing.expectEqual;
56
6test "switch with numbers" {7test "switch with numbers" {
8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10
7 try testSwitchWithNumbers(13);11 try testSwitchWithNumbers(13);
8}12}
913
...@@ -17,6 +21,9 @@ fn testSwitchWithNumbers(x: u32) !void {...@@ -17,6 +21,9 @@ fn testSwitchWithNumbers(x: u32) !void {
17}21}
1822
19test "switch with all ranges" {23test "switch with all ranges" {
24 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
26
20 try expect(testSwitchWithAllRanges(50, 3) == 1);27 try expect(testSwitchWithAllRanges(50, 3) == 1);
21 try expect(testSwitchWithAllRanges(101, 0) == 2);28 try expect(testSwitchWithAllRanges(101, 0) == 2);
22 try expect(testSwitchWithAllRanges(300, 5) == 3);29 try expect(testSwitchWithAllRanges(300, 5) == 3);
...@@ -48,6 +55,9 @@ test "implicit comptime switch" {...@@ -48,6 +55,9 @@ test "implicit comptime switch" {
48}55}
4956
50test "switch on enum" {57test "switch on enum" {
58 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
59 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
60
51 const fruit = Fruit.Orange;61 const fruit = Fruit.Orange;
52 nonConstSwitchOnEnum(fruit);62 nonConstSwitchOnEnum(fruit);
53}63}
...@@ -65,6 +75,9 @@ fn nonConstSwitchOnEnum(fruit: Fruit) void {...@@ -65,6 +75,9 @@ fn nonConstSwitchOnEnum(fruit: Fruit) void {
65}75}
6676
67test "switch statement" {77test "switch statement" {
78 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
79 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
80
68 try nonConstSwitch(SwitchStatementFoo.C);81 try nonConstSwitch(SwitchStatementFoo.C);
69}82}
70fn nonConstSwitch(foo: SwitchStatementFoo) !void {83fn nonConstSwitch(foo: SwitchStatementFoo) !void {
...@@ -79,6 +92,10 @@ fn nonConstSwitch(foo: SwitchStatementFoo) !void {...@@ -79,6 +92,10 @@ fn nonConstSwitch(foo: SwitchStatementFoo) !void {
79const SwitchStatementFoo = enum { A, B, C, D };92const SwitchStatementFoo = enum { A, B, C, D };
8093
81test "switch with multiple expressions" {94test "switch with multiple expressions" {
95 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
96 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
97 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
98
82 const x = switch (returnsFive()) {99 const x = switch (returnsFive()) {
83 1, 2, 3 => 1,100 1, 2, 3 => 1,
84 4, 5, 6 => 2,101 4, 5, 6 => 2,
...@@ -91,6 +108,9 @@ fn returnsFive() i32 {...@@ -91,6 +108,9 @@ fn returnsFive() i32 {
91}108}
92109
93test "switch on type" {110test "switch on type" {
111 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
112 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
113
94 try expect(trueIfBoolFalseOtherwise(bool));114 try expect(trueIfBoolFalseOtherwise(bool));
95 try expect(!trueIfBoolFalseOtherwise(i32));115 try expect(!trueIfBoolFalseOtherwise(i32));
96}116}
...@@ -103,6 +123,10 @@ fn trueIfBoolFalseOtherwise(comptime T: type) bool {...@@ -103,6 +123,10 @@ fn trueIfBoolFalseOtherwise(comptime T: type) bool {
103}123}
104124
105test "switching on booleans" {125test "switching on booleans" {
126 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
127 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
128 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
129
106 try testSwitchOnBools();130 try testSwitchOnBools();
107 comptime try testSwitchOnBools();131 comptime try testSwitchOnBools();
108}132}
...@@ -154,6 +178,9 @@ test "undefined.u0" {...@@ -154,6 +178,9 @@ test "undefined.u0" {
154}178}
155179
156test "switch with disjoint range" {180test "switch with disjoint range" {
181 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
182 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
183
157 var q: u8 = 0;184 var q: u8 = 0;
158 switch (q) {185 switch (q) {
159 0...125 => {},186 0...125 => {},
...@@ -163,6 +190,9 @@ test "switch with disjoint range" {...@@ -163,6 +190,9 @@ test "switch with disjoint range" {
163}190}
164191
165test "switch variable for range and multiple prongs" {192test "switch variable for range and multiple prongs" {
193 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
194 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
195
166 const S = struct {196 const S = struct {
167 fn doTheTest() !void {197 fn doTheTest() !void {
168 var u: u8 = 16;198 var u: u8 = 16;
...@@ -196,6 +226,9 @@ fn poll() void {...@@ -196,6 +226,9 @@ fn poll() void {
196}226}
197227
198test "switch on global mutable var isn't constant-folded" {228test "switch on global mutable var isn't constant-folded" {
229 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
230 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
231
199 while (state < 2) {232 while (state < 2) {
200 poll();233 poll();
201 }234 }
...@@ -208,6 +241,10 @@ const SwitchProngWithVarEnum = union(enum) {...@@ -208,6 +241,10 @@ const SwitchProngWithVarEnum = union(enum) {
208};241};
209242
210test "switch prong with variable" {243test "switch prong with variable" {
244 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
245 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
246 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
247
211 try switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 });248 try switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 });
212 try switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 });249 try switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 });
213 try switchProngWithVarFn(SwitchProngWithVarEnum{ .Meh = {} });250 try switchProngWithVarFn(SwitchProngWithVarEnum{ .Meh = {} });
...@@ -228,6 +265,9 @@ fn switchProngWithVarFn(a: SwitchProngWithVarEnum) !void {...@@ -228,6 +265,9 @@ fn switchProngWithVarFn(a: SwitchProngWithVarEnum) !void {
228}265}
229266
230test "switch on enum using pointer capture" {267test "switch on enum using pointer capture" {
268 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
269 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
270
231 try testSwitchEnumPtrCapture();271 try testSwitchEnumPtrCapture();
232 comptime try testSwitchEnumPtrCapture();272 comptime try testSwitchEnumPtrCapture();
233}273}
...@@ -245,6 +285,10 @@ fn testSwitchEnumPtrCapture() !void {...@@ -245,6 +285,10 @@ fn testSwitchEnumPtrCapture() !void {
245}285}
246286
247test "switch handles all cases of number" {287test "switch handles all cases of number" {
288 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
289 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
290 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
291
248 try testSwitchHandleAllCases();292 try testSwitchHandleAllCases();
249 comptime try testSwitchHandleAllCases();293 comptime try testSwitchHandleAllCases();
250}294}
...@@ -282,6 +326,9 @@ fn testSwitchHandleAllCasesRange(x: u8) u8 {...@@ -282,6 +326,9 @@ fn testSwitchHandleAllCasesRange(x: u8) u8 {
282}326}
283327
284test "switch on union with some prongs capturing" {328test "switch on union with some prongs capturing" {
329 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
330 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
331
285 const X = union(enum) {332 const X = union(enum) {
286 a,333 a,
287 b: i32,334 b: i32,
...@@ -311,10 +358,16 @@ fn returnsFalse() bool {...@@ -311,10 +358,16 @@ fn returnsFalse() bool {
311 }358 }
312}359}
313test "switch on const enum with var" {360test "switch on const enum with var" {
361 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
362 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
363
314 try expect(!returnsFalse());364 try expect(!returnsFalse());
315}365}
316366
317test "anon enum literal used in switch on union enum" {367test "anon enum literal used in switch on union enum" {
368 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
369 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
370
318 const Foo = union(enum) {371 const Foo = union(enum) {
319 a: i32,372 a: i32,
320 };373 };
...@@ -328,6 +381,9 @@ test "anon enum literal used in switch on union enum" {...@@ -328,6 +381,9 @@ test "anon enum literal used in switch on union enum" {
328}381}
329382
330test "switch all prongs unreachable" {383test "switch all prongs unreachable" {
384 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
385 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
386
331 try testAllProngsUnreachable();387 try testAllProngsUnreachable();
332 comptime try testAllProngsUnreachable();388 comptime try testAllProngsUnreachable();
333}389}
...@@ -349,6 +405,9 @@ fn switchWithUnreachable(x: i32) i32 {...@@ -349,6 +405,9 @@ fn switchWithUnreachable(x: i32) i32 {
349}405}
350406
351test "capture value of switch with all unreachable prongs" {407test "capture value of switch with all unreachable prongs" {
408 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
409 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
410
352 const x = return_a_number() catch |err| switch (err) {411 const x = return_a_number() catch |err| switch (err) {
353 else => unreachable,412 else => unreachable,
354 };413 };
...@@ -360,6 +419,10 @@ fn return_a_number() anyerror!i32 {...@@ -360,6 +419,10 @@ fn return_a_number() anyerror!i32 {
360}419}
361420
362test "switch on integer with else capturing expr" {421test "switch on integer with else capturing expr" {
422 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
423 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
424 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
425
363 const S = struct {426 const S = struct {
364 fn doTheTest() !void {427 fn doTheTest() !void {
365 var x: i32 = 5;428 var x: i32 = 5;
...@@ -375,7 +438,7 @@ test "switch on integer with else capturing expr" {...@@ -375,7 +438,7 @@ test "switch on integer with else capturing expr" {
375}438}
376439
377test "else prong of switch on error set excludes other cases" {440test "else prong of switch on error set excludes other cases" {
378 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO441 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
379442
380 const S = struct {443 const S = struct {
381 fn doTheTest() !void {444 fn doTheTest() !void {
...@@ -407,7 +470,7 @@ test "else prong of switch on error set excludes other cases" {...@@ -407,7 +470,7 @@ test "else prong of switch on error set excludes other cases" {
407}470}
408471
409test "switch prongs with error set cases make a new error set type for capture value" {472test "switch prongs with error set cases make a new error set type for capture value" {
410 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO473 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
411474
412 const S = struct {475 const S = struct {
413 fn doTheTest() !void {476 fn doTheTest() !void {
...@@ -441,6 +504,9 @@ test "switch prongs with error set cases make a new error set type for capture v...@@ -441,6 +504,9 @@ test "switch prongs with error set cases make a new error set type for capture v
441}504}
442505
443test "return result loc and then switch with range implicit casted to error union" {506test "return result loc and then switch with range implicit casted to error union" {
507 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
508 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
509
444 const S = struct {510 const S = struct {
445 fn doTheTest() !void {511 fn doTheTest() !void {
446 try expect((func(0xb) catch unreachable) == 0xb);512 try expect((func(0xb) catch unreachable) == 0xb);
...@@ -457,6 +523,10 @@ test "return result loc and then switch with range implicit casted to error unio...@@ -457,6 +523,10 @@ test "return result loc and then switch with range implicit casted to error unio
457}523}
458524
459test "switch with null and T peer types and inferred result location type" {525test "switch with null and T peer types and inferred result location type" {
526 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
527 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
528 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
529
460 const S = struct {530 const S = struct {
461 fn doTheTest(c: u8) !void {531 fn doTheTest(c: u8) !void {
462 if (switch (c) {532 if (switch (c) {
...@@ -473,7 +543,7 @@ test "switch with null and T peer types and inferred result location type" {...@@ -473,7 +543,7 @@ test "switch with null and T peer types and inferred result location type" {
473}543}
474544
475test "switch prongs with cases with identical payload types" {545test "switch prongs with cases with identical payload types" {
476 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO546 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
477547
478 const Union = union(enum) {548 const Union = union(enum) {
479 A: usize,549 A: usize,
...@@ -515,7 +585,11 @@ test "switch prongs with cases with identical payload types" {...@@ -515,7 +585,11 @@ test "switch prongs with cases with identical payload types" {
515}585}
516586
517test "switch on pointer type" {587test "switch on pointer type" {
518 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO588 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
589 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
590 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
591 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
592 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
519593
520 const S = struct {594 const S = struct {
521 const X = struct {595 const X = struct {
...@@ -544,7 +618,7 @@ test "switch on pointer type" {...@@ -544,7 +618,7 @@ test "switch on pointer type" {
544}618}
545619
546test "switch on error set with single else" {620test "switch on error set with single else" {
547 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO621 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
548622
549 const S = struct {623 const S = struct {
550 fn doTheTest() !void {624 fn doTheTest() !void {
...@@ -563,7 +637,7 @@ test "switch on error set with single else" {...@@ -563,7 +637,7 @@ test "switch on error set with single else" {
563}637}
564638
565test "switch capture copies its payload" {639test "switch capture copies its payload" {
566 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO640 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
567641
568 const S = struct {642 const S = struct {
569 fn doTheTest() !void {643 fn doTheTest() !void {
test/behavior/union.zig+7-7
...@@ -878,8 +878,6 @@ test "union with comptime_int tag" {...@@ -878,8 +878,6 @@ test "union with comptime_int tag" {
878}878}
879879
880test "extern union doesn't trigger field check at comptime" {880test "extern union doesn't trigger field check at comptime" {
881 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
882
883 const U = extern union {881 const U = extern union {
884 x: u32,882 x: u32,
885 y: u8,883 y: u8,
...@@ -890,7 +888,8 @@ test "extern union doesn't trigger field check at comptime" {...@@ -890,7 +888,8 @@ test "extern union doesn't trigger field check at comptime" {
890}888}
891889
892test "anonymous union literal syntax" {890test "anonymous union literal syntax" {
893 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO891 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
892 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
894893
895 const S = struct {894 const S = struct {
896 const Number = union {895 const Number = union {
...@@ -914,7 +913,8 @@ test "anonymous union literal syntax" {...@@ -914,7 +913,8 @@ test "anonymous union literal syntax" {
914}913}
915914
916test "function call result coerces from tagged union to the tag" {915test "function call result coerces from tagged union to the tag" {
917 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO916 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
917 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
918918
919 const S = struct {919 const S = struct {
920 const Arch = union(enum) {920 const Arch = union(enum) {
...@@ -1104,9 +1104,9 @@ test "union enum type gets a separate scope" {...@@ -1104,9 +1104,9 @@ test "union enum type gets a separate scope" {
1104test "global variable struct contains union initialized to non-most-aligned field" {1104test "global variable struct contains union initialized to non-most-aligned field" {
1105 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO1105 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1106 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1106 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1107 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;1107 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1108 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;1108 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1109 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1109 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11101110
1111 const T = struct {1111 const T = struct {
1112 const U = union(enum) {1112 const U = union(enum) {