From c349191b75811f8a21e26f8b175483449fae1638 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 12 Feb 2022 21:13:07 -0700 Subject: organize behavior tests moving towards disabling failing tests on an individual basis --- test/behavior/array.zig | 350 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 350 insertions(+) (limited to 'test/behavior/array.zig') diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 0450d0781b..23820e71b5 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -222,3 +222,353 @@ test "anonymous list literal syntax" { try S.doTheTest(); comptime try S.doTheTest(); } + +var s_array: [8]Sub = undefined; +const Sub = struct { b: u8 }; +const Str = struct { a: []Sub }; +test "set global var array via slice embedded in struct" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + var s = Str{ .a = s_array[0..] }; + + s.a[0].b = 1; + s.a[1].b = 2; + s.a[2].b = 3; + + try expect(s_array[0].b == 1); + try expect(s_array[1].b == 2); + try expect(s_array[2].b == 3); +} + +test "read/write through global variable array of struct fields initialized via array mult" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + fn doTheTest() !void { + try expect(storage[0].term == 1); + storage[0] = MyStruct{ .term = 123 }; + try expect(storage[0].term == 123); + } + + pub const MyStruct = struct { + term: usize, + }; + + var storage: [1]MyStruct = [_]MyStruct{MyStruct{ .term = 1 }} ** 1; + }; + try S.doTheTest(); +} + +test "implicit cast single-item pointer" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + try testImplicitCastSingleItemPtr(); + comptime try testImplicitCastSingleItemPtr(); +} + +fn testImplicitCastSingleItemPtr() !void { + var byte: u8 = 100; + const slice = @as(*[1]u8, &byte)[0..]; + slice[0] += 1; + try expect(byte == 101); +} + +fn testArrayByValAtComptime(b: [2]u8) u8 { + return b[0]; +} + +test "comptime evaluating function that takes array by value" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const arr = [_]u8{ 1, 2 }; + const x = comptime testArrayByValAtComptime(arr); + const y = comptime testArrayByValAtComptime(arr); + try expect(x == 1); + try expect(y == 1); +} + +test "runtime initialize array elem and then implicit cast to slice" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + var two: i32 = 2; + const x: []const i32 = &[_]i32{two}; + try expect(x[0] == 2); +} + +test "array literal as argument to function" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + fn entry(two: i32) !void { + try foo(&[_]i32{ 1, 2, 3 }); + try foo(&[_]i32{ 1, two, 3 }); + try foo2(true, &[_]i32{ 1, 2, 3 }); + try foo2(true, &[_]i32{ 1, two, 3 }); + } + fn foo(x: []const i32) !void { + try expect(x[0] == 1); + try expect(x[1] == 2); + try expect(x[2] == 3); + } + fn foo2(trash: bool, x: []const i32) !void { + try expect(trash); + try expect(x[0] == 1); + try expect(x[1] == 2); + try expect(x[2] == 3); + } + }; + try S.entry(2); + comptime try S.entry(2); +} + +test "double nested array to const slice cast in array literal" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + fn entry(two: i32) !void { + const cases = [_][]const []const i32{ + &[_][]const i32{&[_]i32{1}}, + &[_][]const i32{&[_]i32{ 2, 3 }}, + &[_][]const i32{ + &[_]i32{4}, + &[_]i32{ 5, 6, 7 }, + }, + }; + try check(&cases); + + const cases2 = [_][]const i32{ + &[_]i32{1}, + &[_]i32{ two, 3 }, + }; + try expect(cases2.len == 2); + try expect(cases2[0].len == 1); + try expect(cases2[0][0] == 1); + try expect(cases2[1].len == 2); + try expect(cases2[1][0] == 2); + try expect(cases2[1][1] == 3); + + const cases3 = [_][]const []const i32{ + &[_][]const i32{&[_]i32{1}}, + &[_][]const i32{&[_]i32{ two, 3 }}, + &[_][]const i32{ + &[_]i32{4}, + &[_]i32{ 5, 6, 7 }, + }, + }; + try check(&cases3); + } + + fn check(cases: []const []const []const i32) !void { + try expect(cases.len == 3); + try expect(cases[0].len == 1); + try expect(cases[0][0].len == 1); + try expect(cases[0][0][0] == 1); + try expect(cases[1].len == 1); + try expect(cases[1][0].len == 2); + try expect(cases[1][0][0] == 2); + try expect(cases[1][0][1] == 3); + try expect(cases[2].len == 2); + try expect(cases[2][0].len == 1); + try expect(cases[2][0][0] == 4); + try expect(cases[2][1].len == 3); + try expect(cases[2][1][0] == 5); + try expect(cases[2][1][1] == 6); + try expect(cases[2][1][2] == 7); + } + }; + try S.entry(2); + comptime try S.entry(2); +} + +test "anonymous literal in array" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + const Foo = struct { + a: usize = 2, + b: usize = 4, + }; + fn doTheTest() !void { + var array: [2]Foo = .{ + .{ .a = 3 }, + .{ .b = 3 }, + }; + try expect(array[0].a == 3); + try expect(array[0].b == 4); + try expect(array[1].a == 2); + try expect(array[1].b == 3); + } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "access the null element of a null terminated array" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + fn doTheTest() !void { + var array: [4:0]u8 = .{ 'a', 'o', 'e', 'u' }; + try expect(array[4] == 0); + var len: usize = 4; + try expect(array[len] == 0); + } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "type deduction for array subscript expression" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + fn doTheTest() !void { + var array = [_]u8{ 0x55, 0xAA }; + var v0 = true; + try expect(@as(u8, 0xAA) == array[if (v0) 1 else 0]); + var v1 = false; + try expect(@as(u8, 0x55) == array[if (v1) 1 else 0]); + } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "sentinel element count towards the ABI size calculation" { + if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + fn doTheTest() !void { + const T = packed struct { + fill_pre: u8 = 0x55, + data: [0:0]u8 = undefined, + fill_post: u8 = 0xAA, + }; + var x = T{}; + var as_slice = mem.asBytes(&x); + try expect(@as(usize, 3) == as_slice.len); + try expect(@as(u8, 0x55) == as_slice[0]); + try expect(@as(u8, 0xAA) == as_slice[2]); + } + }; + + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "zero-sized array with recursive type definition" { + if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const U = struct { + fn foo(comptime T: type, comptime n: usize) type { + return struct { + s: [n]T, + x: usize = n, + }; + } + }; + + const S = struct { + list: U.foo(@This(), 0), + }; + + var t: S = .{ .list = .{ .s = undefined } }; + try expect(@as(usize, 0) == t.list.x); +} + +test "type coercion of anon struct literal to array" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + const U = union { + a: u32, + b: bool, + c: []const u8, + }; + + fn doTheTest() !void { + var x1: u8 = 42; + const t1 = .{ x1, 56, 54 }; + var arr1: [3]u8 = t1; + try expect(arr1[0] == 42); + try expect(arr1[1] == 56); + try expect(arr1[2] == 54); + + if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (@import("builtin").zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + + var x2: U = .{ .a = 42 }; + const t2 = .{ x2, .{ .b = true }, .{ .c = "hello" } }; + var arr2: [3]U = t2; + try expect(arr2[0].a == 42); + try expect(arr2[1].b == true); + try expect(mem.eql(u8, arr2[2].c, "hello")); + } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "type coercion of pointer to anon struct literal to pointer to array" { + if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + const U = union { + a: u32, + b: bool, + c: []const u8, + }; + + fn doTheTest() !void { + var x1: u8 = 42; + const t1 = &.{ x1, 56, 54 }; + var arr1: *const [3]u8 = t1; + try expect(arr1[0] == 42); + try expect(arr1[1] == 56); + try expect(arr1[2] == 54); + + var x2: U = .{ .a = 42 }; + const t2 = &.{ x2, .{ .b = true }, .{ .c = "hello" } }; + var arr2: *const [3]U = t2; + try expect(arr2[0].a == 42); + try expect(arr2[1].b == true); + try expect(mem.eql(u8, arr2[2].c, "hello")); + } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} -- cgit v1.2.3 From 22895f5616c663bb7b8ad9866c29d00bc4bc315c Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Mon, 14 Feb 2022 22:33:01 +0100 Subject: stage2 AArch64: Enable behavior testing --- src/arch/aarch64/CodeGen.zig | 34 ++++++++++++++++++++++++++++++---- test/behavior.zig | 2 +- test/behavior/align.zig | 18 ++++++++++++++++++ test/behavior/alignof.zig | 1 + test/behavior/array.zig | 27 +++++++++++++++++++++++++++ test/behavior/basic.zig | 32 ++++++++++++++++++++++++++++++++ test/behavior/bit_shifting.zig | 1 + test/behavior/bugs/1381.zig | 1 + test/behavior/bugs/1486.zig | 2 ++ test/behavior/bugs/1735.zig | 1 + test/behavior/bugs/1741.zig | 1 + test/behavior/bugs/2006.zig | 1 + test/behavior/bugs/2578.zig | 1 + test/behavior/bugs/3007.zig | 1 + test/behavior/bugs/3112.zig | 1 + test/behavior/bugs/3367.zig | 1 + test/behavior/bugs/394.zig | 1 + test/behavior/bugs/656.zig | 1 + test/behavior/bugs/7250.zig | 1 + test/behavior/cast.zig | 36 ++++++++++++++++++++++++++++++++++++ test/behavior/fn_delegation.zig | 1 + test/behavior/ir_block_deps.zig | 1 + test/behavior/optional.zig | 10 ++++++++++ test/behavior/reflection.zig | 1 + test/behavior/slice.zig | 14 ++++++++++++++ test/behavior/struct.zig | 28 ++++++++++++++++++++++++++++ test/behavior/truncate.zig | 9 +++++++++ test/behavior/var_args.zig | 3 +++ 28 files changed, 226 insertions(+), 5 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 55c8c64794..b9d5a29f18 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -1029,14 +1029,16 @@ fn binOpRegister( if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs); const mir_tag: Mir.Inst.Tag = switch (tag) { - .add => .add_shifted_register, - .sub => .sub_shifted_register, + .add, .ptr_add => .add_shifted_register, + .sub, .ptr_sub => .sub_shifted_register, .xor => .eor_shifted_register, else => unreachable, }; const mir_data: Mir.Inst.Data = switch (tag) { .add, .sub, + .ptr_add, + .ptr_sub, => .{ .rrr_imm6_shift = .{ .rd = dest_reg, .rn = lhs_reg, @@ -1225,7 +1227,24 @@ fn binOp( }, .ptr_add, .ptr_sub, - => return self.fail("TODO ptr_add, ptr_sub", .{}), + => { + switch (lhs_ty.zigTypeTag()) { + .Pointer => { + const ptr_ty = lhs_ty; + const pointee_ty = switch (ptr_ty.ptrSize()) { + .One => ptr_ty.childType().childType(), // ptr to array, so get array element type + else => ptr_ty.childType(), + }; + + if (pointee_ty.abiSize(self.target.*) > 1) { + return self.fail("TODO ptr_add, ptr_sub with more element sizes", .{}); + } + + return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); + }, + else => unreachable, + } + }, else => unreachable, } } @@ -1439,7 +1458,14 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { /// E to E!T fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement wrap errunion error for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const error_union_ty = self.air.getRefType(ty_op.ty); + const payload_ty = error_union_ty.errorUnionPayload(); + const mcv = try self.resolveInst(ty_op.operand); + if (!payload_ty.hasRuntimeBits()) break :result mcv; + + return self.fail("TODO implement wrap errunion error for non-empty payloads", .{}); + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } diff --git a/test/behavior.zig b/test/behavior.zig index db6863a8b0..abfd8fb0bf 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -54,7 +54,7 @@ test { _ = @import("behavior/decltest.zig"); } - if (builtin.zig_backend != .stage2_arm and builtin.zig_backend != .stage2_x86_64) { + if (builtin.zig_backend != .stage2_arm and builtin.zig_backend != .stage2_x86_64 and builtin.zig_backend != .stage2_aarch64) { // Tests that pass (partly) for stage1, llvm backend, C backend, wasm backend. _ = @import("behavior/bitcast.zig"); _ = @import("behavior/bugs/624.zig"); diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 96278524c0..a8d8fcd206 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -27,6 +27,7 @@ test "default alignment allows unspecified in type syntax" { } test "implicitly decreasing pointer alignment" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const a: u32 align(4) = 3; const b: u32 align(8) = 4; try expect(addUnaligned(&a, &b) == 7); @@ -37,6 +38,7 @@ fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 { } test "@alignCast pointers" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var x: u32 align(4) = 1; expectsOnly1(&x); try expect(x == 2); @@ -102,6 +104,7 @@ fn fnWithAlignedStack() i32 { } test "implicitly decreasing slice alignment" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const a: u32 align(4) = 3; @@ -113,6 +116,7 @@ fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { } test "specifying alignment allows pointer cast" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try testBytesAlign(0x33); @@ -124,6 +128,7 @@ fn testBytesAlign(b: u8) !void { } test "@alignCast slices" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array align(4) = [_]u32{ 1, 1 }; @@ -139,6 +144,7 @@ fn sliceExpects4(slice: []align(4) u32) void { } test "return error union with 128-bit integer" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try expect(3 == try give()); @@ -148,6 +154,7 @@ fn give() anyerror!u128 { } test "page aligned array on stack" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -173,6 +180,7 @@ fn noop1() align(1) void {} fn noop4() align(4) void {} test "function alignment" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -189,6 +197,7 @@ test "function alignment" { } test "implicitly decreasing fn alignment" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; @@ -216,6 +225,7 @@ fn alignedBig() align(16) i32 { } test "@alignCast functions" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; @@ -239,6 +249,7 @@ fn simple4() align(4) i32 { } test "generic function with align param" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; @@ -260,6 +271,7 @@ fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 { } test "runtime known array index has best alignment possible" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -302,6 +314,7 @@ fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) !void { } test "alignment of function with c calling convention" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; var runtime_nothing = ¬hing; @@ -318,6 +331,7 @@ const DefaultAligned = struct { }; test "read 128-bit field from default aligned struct in stack memory" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -337,6 +351,7 @@ var default_aligned_global = DefaultAligned{ }; test "read 128-bit field from default aligned struct in global memory" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; @@ -348,6 +363,7 @@ test "read 128-bit field from default aligned struct in global memory" { } test "struct field explicit alignment" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; @@ -369,6 +385,7 @@ test "struct field explicit alignment" { } test "align(@alignOf(T)) T does not force resolution of T" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; @@ -397,6 +414,7 @@ test "align(@alignOf(T)) T does not force resolution of T" { } test "align(N) on functions" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; diff --git a/test/behavior/alignof.zig b/test/behavior/alignof.zig index 749855db52..5a49146694 100644 --- a/test/behavior/alignof.zig +++ b/test/behavior/alignof.zig @@ -11,6 +11,7 @@ const Foo = struct { }; test "@alignOf(T) before referencing T" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 23820e71b5..e93f0f3e90 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -6,6 +6,7 @@ const expect = testing.expect; const expectEqual = testing.expectEqual; test "array to slice" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const a: u32 align(4) = 3; @@ -20,6 +21,7 @@ test "array to slice" { } test "arrays" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array: [5]u32 = undefined; @@ -46,6 +48,7 @@ fn getArrayLen(a: []const u32) usize { } test "array init with mult" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const a = 'a'; @@ -57,6 +60,7 @@ test "array init with mult" { } test "array literal with explicit type" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const hex_mult: [4]u16 = .{ 4096, 256, 16, 1 }; @@ -86,6 +90,7 @@ const ArrayDotLenConstExpr = struct { const some_array = [_]u8{ 0, 1, 2, 3 }; test "array literal with specified size" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array = [2]u8{ 1, 2 }; @@ -94,6 +99,7 @@ test "array literal with specified size" { } test "array len field" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var arr = [4]u8{ 0, 0, 0, 0 }; @@ -105,6 +111,7 @@ test "array len field" { } test "array with sentinels" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { @@ -134,6 +141,7 @@ test "array with sentinels" { } test "void arrays" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array: [4]void = undefined; @@ -144,6 +152,7 @@ test "void arrays" { } test "nested arrays" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const array_of_strings = [_][]const u8{ "hello", "this", "is", "my", "thing" }; @@ -157,6 +166,7 @@ test "nested arrays" { } test "implicit comptime in array type size" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var arr: [plusOne(10)]bool = undefined; @@ -168,6 +178,7 @@ fn plusOne(x: u32) u32 { } test "single-item pointer to array indexing and slicing" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try testSingleItemPtrArrayIndexSlice(); @@ -193,6 +204,7 @@ fn doSomeMangling(array: *[4]u8) void { } test "implicit cast zero sized array ptr to slice" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; { @@ -208,6 +220,7 @@ test "implicit cast zero sized array ptr to slice" { } test "anonymous list literal syntax" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { @@ -227,6 +240,7 @@ var s_array: [8]Sub = undefined; const Sub = struct { b: u8 }; const Str = struct { a: []Sub }; test "set global var array via slice embedded in struct" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -243,6 +257,7 @@ test "set global var array via slice embedded in struct" { } test "read/write through global variable array of struct fields initialized via array mult" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -264,6 +279,7 @@ test "read/write through global variable array of struct fields initialized via } test "implicit cast single-item pointer" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -284,6 +300,7 @@ fn testArrayByValAtComptime(b: [2]u8) u8 { } test "comptime evaluating function that takes array by value" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -296,6 +313,7 @@ test "comptime evaluating function that takes array by value" { } test "runtime initialize array elem and then implicit cast to slice" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -306,6 +324,7 @@ test "runtime initialize array elem and then implicit cast to slice" { } test "array literal as argument to function" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -334,6 +353,7 @@ test "array literal as argument to function" { } test "double nested array to const slice cast in array literal" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -395,6 +415,7 @@ test "double nested array to const slice cast in array literal" { } test "anonymous literal in array" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -420,6 +441,7 @@ test "anonymous literal in array" { } test "access the null element of a null terminated array" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -437,6 +459,7 @@ test "access the null element of a null terminated array" { } test "type deduction for array subscript expression" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -455,6 +478,7 @@ test "type deduction for array subscript expression" { } test "sentinel element count towards the ABI size calculation" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -481,6 +505,7 @@ test "sentinel element count towards the ABI size calculation" { } test "zero-sized array with recursive type definition" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -505,6 +530,7 @@ test "zero-sized array with recursive type definition" { } test "type coercion of anon struct literal to array" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -540,6 +566,7 @@ test "type coercion of anon struct literal to array" { } test "type coercion of pointer to anon struct literal to pointer to array" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index 18a24f9b3a..0c2c293d23 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -15,6 +15,7 @@ test "empty function with comments" { } test "truncate" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try expect(testTruncate(0x10fd) == 0xfd); @@ -25,6 +26,7 @@ fn testTruncate(x: u32) u8 { } test "truncate to non-power-of-two integers" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try testTrunc(u32, u1, 0b10101, 0b1); @@ -46,6 +48,7 @@ const g1: i32 = 1233 + 1; var g2: i32 = 0; test "global variables" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(g2 == 0); g2 = g1; try expect(g2 == 1234); @@ -112,6 +115,7 @@ fn first4KeysOfHomeRow() []const u8 { } test "return string from function" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -119,12 +123,14 @@ test "return string from function" { } test "hex escape" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try expect(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello")); } test "multiline string" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const s1 = @@ -137,6 +143,7 @@ test "multiline string" { } test "multiline string comments at start" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const s1 = @@ -149,6 +156,7 @@ test "multiline string comments at start" { } test "multiline string comments at end" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const s1 = @@ -161,6 +169,7 @@ test "multiline string comments at end" { } test "multiline string comments in middle" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const s1 = @@ -173,6 +182,7 @@ test "multiline string comments in middle" { } test "multiline string comments at multiple places" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const s1 = @@ -191,6 +201,7 @@ test "string concatenation" { } test "array mult operator" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try expect(mem.eql(u8, "ab" ** 5, "ababababab")); @@ -216,6 +227,7 @@ test "compile time global reinterpret" { } test "cast undefined" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const array: [100]u8 = undefined; @@ -227,6 +239,7 @@ fn testCastUndefined(x: []const u8) void { } test "implicit cast after unreachable" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try expect(outer() == 1234); @@ -284,6 +297,7 @@ fn fB() []const u8 { } test "call function pointer in struct" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -310,6 +324,7 @@ const FnPtrWrapper = struct { }; test "const ptr from var variable" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var x: u64 = undefined; @@ -326,6 +341,7 @@ fn copy(src: *const u64, dst: *u64) void { } test "call result of if else expression" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -339,6 +355,7 @@ fn f2(x: bool) []const u8 { } test "memcpy and memset intrinsics" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO @@ -361,6 +378,7 @@ fn testMemcpyMemset() !void { } test "variable is allowed to be a pointer to an opaque type" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -374,6 +392,7 @@ fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA { } test "take address of parameter" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -400,6 +419,7 @@ fn testPointerToVoidReturnType2() *const void { } test "array 2D const double ptr" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -419,6 +439,7 @@ fn testArray2DConstDoublePtr(ptr: *const f32) !void { } test "double implicit cast in same expression" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -430,6 +451,7 @@ fn nine() u8 { } test "struct inside function" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try testStructInFn(); @@ -451,6 +473,7 @@ fn testStructInFn() !void { } test "fn call returning scalar optional in equality expression" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(getNull() == null); } @@ -459,6 +482,7 @@ fn getNull() ?*i32 { } test "global variable assignment with optional unwrapping with var initialized to undefined" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { @@ -476,6 +500,7 @@ test "global variable assignment with optional unwrapping with var initialized t var global_foo: *i32 = undefined; test "peer result location with typed parent, runtime condition, comptime prongs" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -550,6 +575,7 @@ test "comptime cast fn to ptr" { } test "equality compare fn ptrs" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; var a = &emptyFn; @@ -557,6 +583,7 @@ test "equality compare fn ptrs" { } test "self reference through fn ptr field" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; @@ -576,6 +603,7 @@ test "self reference through fn ptr field" { } test "global variable initialized to global variable array element" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -593,6 +621,7 @@ var gdt = [_]GDTEntry{ var global_ptr = &gdt[0]; test "global constant is loaded with a runtime-known index" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { @@ -610,6 +639,7 @@ test "global constant is loaded with a runtime-known index" { } test "multiline string literal is null terminated" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -643,6 +673,7 @@ test "explicit cast optional pointers" { } test "pointer comparison" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -655,6 +686,7 @@ fn ptrEql(a: *const []const u8, b: *const []const u8) bool { } test "string concatenation" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; diff --git a/test/behavior/bit_shifting.zig b/test/behavior/bit_shifting.zig index c0b2729bdf..1a01cbd732 100644 --- a/test/behavior/bit_shifting.zig +++ b/test/behavior/bit_shifting.zig @@ -61,6 +61,7 @@ fn ShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, compt } test "sharded table" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; diff --git a/test/behavior/bugs/1381.zig b/test/behavior/bugs/1381.zig index 91a253af24..2f05d2fa96 100644 --- a/test/behavior/bugs/1381.zig +++ b/test/behavior/bugs/1381.zig @@ -12,6 +12,7 @@ const A = union(enum) { }; test "union that needs padding bytes inside an array" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var as = [_]A{ diff --git a/test/behavior/bugs/1486.zig b/test/behavior/bugs/1486.zig index 8f954a3600..91d5b621d2 100644 --- a/test/behavior/bugs/1486.zig +++ b/test/behavior/bugs/1486.zig @@ -1,10 +1,12 @@ const std = @import("std"); const expect = std.testing.expect; +const builtin = @import("builtin"); const ptr = &global; var global: usize = 123; test "constant pointer to global variable causes runtime load" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; global = 1234; try expect(&global == ptr); try expect(ptr.* == 1234); diff --git a/test/behavior/bugs/1735.zig b/test/behavior/bugs/1735.zig index c07bd9472b..556b899de1 100644 --- a/test/behavior/bugs/1735.zig +++ b/test/behavior/bugs/1735.zig @@ -42,6 +42,7 @@ const a = struct { }; test "initialization" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; diff --git a/test/behavior/bugs/1741.zig b/test/behavior/bugs/1741.zig index 280aafc52e..f4cc2101c4 100644 --- a/test/behavior/bugs/1741.zig +++ b/test/behavior/bugs/1741.zig @@ -2,6 +2,7 @@ const std = @import("std"); const builtin = @import("builtin"); test "fixed" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const x: f32 align(128) = 12.34; diff --git a/test/behavior/bugs/2006.zig b/test/behavior/bugs/2006.zig index 4d76230c88..fcacb9a2c6 100644 --- a/test/behavior/bugs/2006.zig +++ b/test/behavior/bugs/2006.zig @@ -6,6 +6,7 @@ const S = struct { p: *S, }; test "bug 2006" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; var a: S = undefined; a = S{ .p = undefined }; diff --git a/test/behavior/bugs/2578.zig b/test/behavior/bugs/2578.zig index 15f5bf0e53..90db296158 100644 --- a/test/behavior/bugs/2578.zig +++ b/test/behavior/bugs/2578.zig @@ -12,6 +12,7 @@ fn bar(pointer: ?*anyopaque) void { } test "fixed" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/3007.zig b/test/behavior/bugs/3007.zig index 0b3cbdc56d..c93bbf8d20 100644 --- a/test/behavior/bugs/3007.zig +++ b/test/behavior/bugs/3007.zig @@ -19,6 +19,7 @@ fn get_foo() Foo.FooError!*Foo { } test "fixed" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/3112.zig b/test/behavior/bugs/3112.zig index 089f3e59f6..ebd8fd1ef3 100644 --- a/test/behavior/bugs/3112.zig +++ b/test/behavior/bugs/3112.zig @@ -12,6 +12,7 @@ fn prev(p: ?State) void { } test "zig test crash" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; diff --git a/test/behavior/bugs/3367.zig b/test/behavior/bugs/3367.zig index f540fdf6df..6468498ab6 100644 --- a/test/behavior/bugs/3367.zig +++ b/test/behavior/bugs/3367.zig @@ -10,6 +10,7 @@ const Mixin = struct { }; test "container member access usingnamespace decls" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var foo = Foo{}; diff --git a/test/behavior/bugs/394.zig b/test/behavior/bugs/394.zig index ec1bd5cc9f..28934c8dd0 100644 --- a/test/behavior/bugs/394.zig +++ b/test/behavior/bugs/394.zig @@ -11,6 +11,7 @@ const expect = @import("std").testing.expect; const builtin = @import("builtin"); test "bug 394 fixed" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const x = S{ diff --git a/test/behavior/bugs/656.zig b/test/behavior/bugs/656.zig index bd93c2b88c..d71dc426f9 100644 --- a/test/behavior/bugs/656.zig +++ b/test/behavior/bugs/656.zig @@ -11,6 +11,7 @@ const Value = struct { }; test "optional if after an if in a switch prong of a switch with 2 prongs in an else" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; try foo(false, true); diff --git a/test/behavior/bugs/7250.zig b/test/behavior/bugs/7250.zig index 27810acea4..ee04847e51 100644 --- a/test/behavior/bugs/7250.zig +++ b/test/behavior/bugs/7250.zig @@ -14,6 +14,7 @@ threadlocal var g_uart0 = nrfx_uart_t{ }; test "reference a global threadlocal variable" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 4028d8c5f1..85e3368441 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -18,6 +18,7 @@ test "integer literal to pointer cast" { } test "peer type resolution: ?T and T" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try expect(peerTypeTAndOptionalT(true, false).? == 0); @@ -94,6 +95,7 @@ test "comptime_int @intToFloat" { } test "@floatToInt" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -116,6 +118,7 @@ fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void { } test "implicitly cast indirect pointer to maybe-indirect pointer" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { @@ -174,6 +177,7 @@ test "@floatCast comptime_int and comptime_float" { } test "coerce undefined to optional" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try expect(MakeType(void).getNull() == null); @@ -193,6 +197,7 @@ fn MakeType(comptime T: type) type { } test "implicit cast from *[N]T to [*c]T" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var x: [4]u16 = [4]u16{ 0, 1, 2, 3 }; @@ -205,6 +210,7 @@ test "implicit cast from *[N]T to [*c]T" { } test "*usize to *void" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var i = @as(usize, 0); var v = @ptrCast(*void, &i); v.* = {}; @@ -230,6 +236,7 @@ test "@intCast to u0 and use the result" { } test "peer result null and comptime_int" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { @@ -253,6 +260,7 @@ test "peer result null and comptime_int" { } test "*const ?[*]const T to [*c]const [*c]const T" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array = [_]u8{ 'o', 'k' }; @@ -264,6 +272,7 @@ test "*const ?[*]const T to [*c]const [*c]const T" { } test "array coersion to undefined at runtime" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @setRuntimeSafety(true); @@ -293,6 +302,7 @@ fn implicitIntLitToOptional() void { } test "return u8 coercing into ?u32 return type" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { @@ -313,6 +323,7 @@ test "cast from ?[*]T to ??[*]T" { } test "peer type unsigned int to signed" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -325,6 +336,7 @@ test "peer type unsigned int to signed" { } test "expected [*c]const u8, found [*:0]const u8" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -384,6 +396,7 @@ fn castToOptionalTypeError(z: i32) !void { } test "implicitly cast from [0]T to anyerror![]T" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -455,6 +468,7 @@ fn testCastConstArrayRefToConstSlice() !void { } test "peer type resolution: error and [N]T" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -689,6 +703,7 @@ test "type coercion related to sentinel-termination" { } test "peer type resolution implicit cast to return type" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -710,6 +725,7 @@ test "peer type resolution implicit cast to return type" { } test "peer type resolution implicit cast to variable type" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -806,6 +822,7 @@ test "comptime float casts" { } test "pointer reinterpret const float to int" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -822,6 +839,7 @@ test "pointer reinterpret const float to int" { } test "implicit cast from [*]T to ?*anyopaque" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -840,6 +858,7 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void { } test "compile time int to ptr of function" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -857,6 +876,7 @@ fn foobar(func: PFN_void) !void { } test "implicit ptr to *anyopaque" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -871,6 +891,7 @@ test "implicit ptr to *anyopaque" { } test "return null from fn() anyerror!?&T" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -887,6 +908,7 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A { } test "peer type resolution: [0]u8 and []const u8" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -907,6 +929,7 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { } test "implicitly cast from [N]T to ?[]const T" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -920,6 +943,7 @@ fn castToOptionalSlice() ?[]const u8 { } test "cast u128 to f128 and back" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -941,6 +965,7 @@ fn cast128Float(x: u128) f128 { } test "implicit cast from *[N]T to ?[*]T" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -956,6 +981,7 @@ test "implicit cast from *[N]T to ?[*]T" { } test "implicit cast from *T to ?*anyopaque" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -970,6 +996,7 @@ fn incrementVoidPtrValue(value: ?*anyopaque) void { } test "implicit cast *[0]T to E![]const u8" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -987,6 +1014,7 @@ test "cast from array reference to fn: comptime fn ptr" { try expect(@ptrToInt(f) == @ptrToInt(&global_array)); } test "cast from array reference to fn: runtime fn ptr" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -996,6 +1024,7 @@ test "cast from array reference to fn: runtime fn ptr" { } test "*const [N]null u8 to ?[]const u8" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -1034,6 +1063,7 @@ test "cast between [*c]T and ?[*:0]T on fn parameter" { var global_struct: struct { f0: usize } = undefined; test "assignment to optional pointer result loc" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -1043,6 +1073,7 @@ test "assignment to optional pointer result loc" { } test "cast between *[N]void and []void" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -1052,6 +1083,7 @@ test "cast between *[N]void and []void" { } test "peer resolve arrays of different size to const slice" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -1065,6 +1097,7 @@ fn boolToStr(b: bool) []const u8 { } test "cast f16 to wider types" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -1083,6 +1116,7 @@ test "cast f16 to wider types" { } test "cast f128 to narrower types" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -1101,6 +1135,7 @@ test "cast f128 to narrower types" { } test "peer type resolution: unreachable, null, slice" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -1119,6 +1154,7 @@ test "peer type resolution: unreachable, null, slice" { } test "cast i8 fn call peers to i32 result" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO diff --git a/test/behavior/fn_delegation.zig b/test/behavior/fn_delegation.zig index 25ec3dea1b..eee8f52490 100644 --- a/test/behavior/fn_delegation.zig +++ b/test/behavior/fn_delegation.zig @@ -32,6 +32,7 @@ fn custom(comptime T: type, comptime num: u64) fn (T) u64 { } test "fn delegation" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const foo = Foo{}; diff --git a/test/behavior/ir_block_deps.zig b/test/behavior/ir_block_deps.zig index cbc5cc2419..d7d50b4be1 100644 --- a/test/behavior/ir_block_deps.zig +++ b/test/behavior/ir_block_deps.zig @@ -18,6 +18,7 @@ fn getErrInt() anyerror!i32 { } test "ir block deps" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index 3caf777195..78788d6556 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -5,6 +5,7 @@ const expect = testing.expect; const expectEqual = testing.expectEqual; test "passing an optional integer as a parameter" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -25,6 +26,7 @@ test "passing an optional integer as a parameter" { pub const EmptyStruct = struct {}; test "optional pointer to size zero struct" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -34,6 +36,7 @@ test "optional pointer to size zero struct" { } test "equality compare optional pointers" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -58,6 +61,7 @@ fn testNullPtrsEql() !void { } test "optional with void type" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -69,6 +73,7 @@ test "optional with void type" { } test "address of unwrap optional" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -89,6 +94,7 @@ test "address of unwrap optional" { } test "nested optional field in struct" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -105,6 +111,7 @@ test "nested optional field in struct" { } test "equality compare optional with non-optional" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -142,6 +149,7 @@ fn test_cmp_optional_non_optional() !void { } test "unwrap function call with optional pointer return value" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -163,6 +171,7 @@ test "unwrap function call with optional pointer return value" { } test "nested orelse" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -189,6 +198,7 @@ test "nested orelse" { } test "self-referential struct through a slice of optional" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO diff --git a/test/behavior/reflection.zig b/test/behavior/reflection.zig index 96c81fe0d0..a181e95b86 100644 --- a/test/behavior/reflection.zig +++ b/test/behavior/reflection.zig @@ -28,6 +28,7 @@ fn dummy(a: bool, b: i32, c: f32) i32 { } test "reflection: @field" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index badaf7ef03..4b73a3a140 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -27,6 +27,7 @@ comptime { } test "slicing" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -68,6 +69,7 @@ test "comptime slice of undefined pointer of length 0" { } test "implicitly cast array of size 0 to slice" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -80,6 +82,7 @@ fn assertLenIsZero(msg: []const u8) !void { } test "access len index of sentinel-terminated slice" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO const S = struct { @@ -129,6 +132,7 @@ test "slice of type" { } test "generic malloc free" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -187,6 +191,7 @@ test "comptime pointer cast array and then slice" { } test "slicing zero length array" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -202,6 +207,7 @@ test "slicing zero length array" { const x = @intToPtr([*]i32, 0x1000)[0..0x500]; const y = x[0x100..]; test "compile time slice of pointer to hard coded address" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -215,6 +221,7 @@ test "compile time slice of pointer to hard coded address" { } test "slice string literal has correct type" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -230,6 +237,7 @@ test "slice string literal has correct type" { } test "result location zero sized array inside struct field implicit cast to slice" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO const E = struct { @@ -240,6 +248,7 @@ test "result location zero sized array inside struct field implicit cast to slic } test "runtime safety lets us slice from len..len" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -252,6 +261,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 { } test "C pointer" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -262,6 +272,7 @@ test "C pointer" { } test "C pointer slice access" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -291,6 +302,7 @@ fn sliceSum(comptime q: []const u8) i32 { } test "slice type with custom alignment" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -305,6 +317,7 @@ test "slice type with custom alignment" { } test "obtaining a null terminated slice" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -350,6 +363,7 @@ test "empty array to slice" { } test "@ptrCast slice to pointer" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index ecdd6a1846..8428ea886f 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -9,6 +9,7 @@ const maxInt = std.math.maxInt; top_level_field: i32, test "top level fields" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var instance = @This(){ @@ -42,6 +43,7 @@ const StructWithFields = struct { }; test "non-packed struct has fields padded out to the required alignment" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const foo = StructWithFields{ .a = 5, .b = 1, .c = 10, .d = 2 }; @@ -65,6 +67,7 @@ const SmallStruct = struct { }; test "lower unnamed constants" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var foo = SmallStruct{ .a = 1, .b = 255 }; try expect(foo.first() == 1); try expect(foo.second() == 255); @@ -83,6 +86,7 @@ const StructFoo = struct { }; test "structs" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var foo: StructFoo = undefined; @@ -101,6 +105,7 @@ fn testMutation(foo: *StructFoo) void { } test "struct byval assign" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var foo1: StructFoo = undefined; @@ -134,6 +139,7 @@ fn returnEmptyStructInstance() StructWithNoFields { } test "fn call of struct field" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const Foo = struct { @@ -165,12 +171,14 @@ const MemberFnTestFoo = struct { }; test "call member function directly" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const instance = MemberFnTestFoo{ .x = 1234 }; const result = MemberFnTestFoo.member(instance); try expect(result == 1234); } test "store member function in variable" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const instance = MemberFnTestFoo{ .x = 1234 }; const memberFn = MemberFnTestFoo.member; const result = memberFn(instance); @@ -178,6 +186,7 @@ test "store member function in variable" { } test "member functions" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const r = MemberFnRand{ .seed = 1234 }; try expect(r.getSeed() == 1234); } @@ -189,6 +198,7 @@ const MemberFnRand = struct { }; test "return struct byval from function" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const bar = makeBar2(1234, 5678); @@ -206,6 +216,7 @@ fn makeBar2(x: i32, y: i32) Bar { } test "call method with mutable reference to struct with no fields" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { @@ -238,6 +249,7 @@ test "usingnamespace within struct scope" { } test "struct field init with catch" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { @@ -296,6 +308,7 @@ const Val = struct { }; test "struct point to self" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -314,6 +327,7 @@ test "struct point to self" { } test "void struct fields" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -334,6 +348,7 @@ const VoidStructFieldsFoo = struct { }; test "return empty struct from fn" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -347,6 +362,7 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 { } test "pass slice of empty struct to fn" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -359,6 +375,7 @@ fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize { } test "self-referencing struct via array member" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -389,6 +406,7 @@ const EmptyStruct = struct { }; test "align 1 field before self referential align 8 field as slice return type" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -413,6 +431,7 @@ const APackedStruct = packed struct { }; test "packed struct" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -438,6 +457,7 @@ const Foo96Bits = packed struct { }; test "packed struct 24bits" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -484,6 +504,7 @@ test "packed struct 24bits" { } test "runtime struct initialization of bitfield" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -523,6 +544,7 @@ const Bitfields = packed struct { }; test "native bit field understands endianness" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -546,6 +568,7 @@ test "native bit field understands endianness" { } test "implicit cast packed struct field to const ptr" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -581,6 +604,7 @@ test "zero-bit field in packed struct" { } test "packed struct with non-ABI-aligned field" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -610,6 +634,7 @@ const bit_field_1 = BitField1{ }; test "bit field access" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -642,6 +667,7 @@ fn getC(data: *const BitField1) u2 { } test "default struct initialization fields" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -907,6 +933,7 @@ test "packed struct field passed to generic function" { } test "anonymous struct literal syntax" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -1100,6 +1127,7 @@ test "type coercion of pointer to anon struct literal to pointer to struct" { } test "packed struct with undefined initializers" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/truncate.zig b/test/behavior/truncate.zig index 001ba538b2..7fe5b8ecb6 100644 --- a/test/behavior/truncate.zig +++ b/test/behavior/truncate.zig @@ -3,6 +3,7 @@ const builtin = @import("builtin"); const expect = std.testing.expect; test "truncate u0 to larger integer allowed and has comptime known result" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var x: u0 = 0; @@ -11,6 +12,7 @@ test "truncate u0 to larger integer allowed and has comptime known result" { } test "truncate.u0.literal" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var z = @truncate(u0, 0); @@ -18,6 +20,7 @@ test "truncate.u0.literal" { } test "truncate.u0.const" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const c0: usize = 0; @@ -26,6 +29,7 @@ test "truncate.u0.const" { } test "truncate.u0.var" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var d: u8 = 2; @@ -34,6 +38,7 @@ test "truncate.u0.var" { } test "truncate i0 to larger integer allowed and has comptime known result" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var x: i0 = 0; @@ -42,6 +47,7 @@ test "truncate i0 to larger integer allowed and has comptime known result" { } test "truncate.i0.literal" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var z = @truncate(i0, 0); @@ -49,6 +55,7 @@ test "truncate.i0.literal" { } test "truncate.i0.const" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const c0: isize = 0; @@ -57,6 +64,7 @@ test "truncate.i0.const" { } test "truncate.i0.var" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var d: i8 = 2; @@ -65,6 +73,7 @@ test "truncate.i0.var" { } test "truncate on comptime integer" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var x = @truncate(u16, 9999); diff --git a/test/behavior/var_args.zig b/test/behavior/var_args.zig index 63b8c35e1b..0e37c845b6 100644 --- a/test/behavior/var_args.zig +++ b/test/behavior/var_args.zig @@ -25,6 +25,7 @@ fn readFirstVarArg(args: anytype) void { } test "send void arg to var args" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -84,6 +85,7 @@ fn foo2(args: anytype) bool { } test "array of var args functions" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -93,6 +95,7 @@ test "array of var args functions" { } test "pass zero length array to var args param" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO -- cgit v1.2.3 From 78e6f9c44c054b922ed1eaafcc4534edcf2dc9ba Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 11 Feb 2022 16:13:05 +0100 Subject: x64: fix ptr_add However, still missing is taking into account pointer alignment when performing arithmetic. --- src/arch/x86_64/CodeGen.zig | 28 +++++++++++++++++++++++++--- test/behavior/align.zig | 1 + test/behavior/array.zig | 1 + 3 files changed, 27 insertions(+), 3 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index df874dd492..d91beceabe 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2217,7 +2217,26 @@ fn genBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: // Now for step 2, we assing an MIR instruction const air_tags = self.air.instructions.items(.tag); switch (air_tags[inst]) { - .add, .addwrap, .ptr_add => try self.genBinMathOpMir(.add, dst_ty, dst_mcv, src_mcv), + .ptr_add => { + // TODO clean this up + // TODO take into account alignment + const elem_size = dst_ty.elemType2().abiSize(self.target.*); + const dst_reg = blk: { + switch (dst_mcv) { + .register => |reg| break :blk reg, + else => { + src_mcv.freezeIfRegister(&self.register_manager); + defer src_mcv.freezeIfRegister(&self.register_manager); + const reg = try self.copyToTmpRegister(dst_ty, dst_mcv); + break :blk reg; + }, + } + }; + try self.genIMulOpMir(dst_ty, .{ .register = dst_reg }, .{ .immediate = elem_size }); + dst_mcv = MCValue{ .register = dst_reg }; + try self.genBinMathOpMir(.add, dst_ty, dst_mcv, src_mcv); + }, + .add, .addwrap => try self.genBinMathOpMir(.add, dst_ty, dst_mcv, src_mcv), .bool_or, .bit_or => try self.genBinMathOpMir(.@"or", dst_ty, dst_mcv, src_mcv), .bool_and, .bit_and => try self.genBinMathOpMir(.@"and", dst_ty, dst_mcv, src_mcv), .sub, .subwrap => try self.genBinMathOpMir(.sub, dst_ty, dst_mcv, src_mcv), @@ -2244,8 +2263,11 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC .none => unreachable, .undef => try self.genSetReg(dst_ty, dst_reg, .undef), .dead, .unreach => unreachable, - .ptr_stack_offset => |off| { - return self.genBinMathOpMir(mir_tag, dst_ty, dst_mcv, .{ .immediate = @bitCast(u32, off) }); + .ptr_stack_offset => { + self.register_manager.freezeRegs(&.{dst_reg}); + defer self.register_manager.unfreezeRegs(&.{dst_reg}); + const reg = try self.copyToTmpRegister(dst_ty, src_mcv); + return self.genBinMathOpMir(mir_tag, dst_ty, dst_mcv, .{ .register = reg }); }, .ptr_embedded_in_code => unreachable, .register => |src_reg| { diff --git a/test/behavior/align.zig b/test/behavior/align.zig index a8d8fcd206..8a315ecab0 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -106,6 +106,7 @@ fn fnWithAlignedStack() i32 { test "implicitly decreasing slice alignment" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const a: u32 align(4) = 3; const b: u32 align(8) = 4; diff --git a/test/behavior/array.zig b/test/behavior/array.zig index e93f0f3e90..7828963a1c 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -8,6 +8,7 @@ const expectEqual = testing.expectEqual; test "array to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const a: u32 align(4) = 3; const b: u32 align(8) = 4; -- cgit v1.2.3 From abfaf8382b58d8bdfa029b74205d385cbc73d78e Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 17 Feb 2022 17:54:37 +0100 Subject: x64: implement array_elem_val when array fits in register --- src/arch/x86_64/CodeGen.zig | 46 ++++++++++++++++++++++++++++++--------------- test/behavior/array.zig | 20 ++++++-------------- 2 files changed, 37 insertions(+), 29 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 7b96ea4baa..cc3953e57b 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1589,21 +1589,37 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { self.register_manager.freezeRegs(&.{offset_reg}); defer self.register_manager.unfreezeRegs(&.{offset_reg}); - const addr_reg = try self.register_manager.allocReg(null); - switch (array) { - .stack_offset => |off| { - // lea reg, [rbp] - _ = try self.addInst(.{ - .tag = .lea, - .ops = (Mir.Ops{ - .reg1 = addr_reg.to64(), - .reg2 = .rbp, - }).encode(), - .data = .{ .imm = @bitCast(u32, -off) }, - }); - }, - else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), - } + const addr_reg = blk: { + const off = inner: { + switch (array) { + .register => { + const off = @intCast(i32, try self.allocMem( + inst, + @intCast(u32, array_ty.abiSize(self.target.*)), + array_ty.abiAlignment(self.target.*), + )); + try self.genSetStack(array_ty, off, array); + break :inner off; + }, + .stack_offset => |off| { + break :inner off; + }, + else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), + } + }; + const addr_reg = try self.register_manager.allocReg(null); + // lea reg, [rbp] + _ = try self.addInst(.{ + .tag = .lea, + .ops = (Mir.Ops{ + .reg1 = addr_reg.to64(), + .reg2 = .rbp, + }).encode(), + .data = .{ .imm = @bitCast(u32, -off) }, + }); + break :blk addr_reg.to64(); + }; + // TODO we could allocate register here, but need to expect addr register and potentially // offset register. const dst_mcv = try self.allocRegOrMem(inst, false); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 7828963a1c..b4a4c37d95 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -8,7 +8,6 @@ const expectEqual = testing.expectEqual; test "array to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const a: u32 align(4) = 3; const b: u32 align(8) = 4; @@ -62,7 +61,7 @@ test "array init with mult" { test "array literal with explicit type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const hex_mult: [4]u16 = .{ 4096, 256, 16, 1 }; @@ -71,7 +70,7 @@ test "array literal with explicit type" { } test "array literal with inferred length" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const hex_mult = [_]u16{ 4096, 256, 16, 1 }; @@ -92,7 +91,7 @@ const some_array = [_]u8{ 0, 1, 2, 3 }; test "array literal with specified size" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array = [2]u8{ 1, 2 }; try expect(array[0] == 1); @@ -101,7 +100,7 @@ test "array literal with specified size" { test "array len field" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var arr = [4]u8{ 0, 0, 0, 0 }; var ptr = &arr; @@ -143,7 +142,7 @@ test "array with sentinels" { test "void arrays" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array: [4]void = undefined; array[0] = void{}; @@ -222,7 +221,7 @@ test "implicit cast zero sized array ptr to slice" { test "anonymous list literal syntax" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest() !void { @@ -282,7 +281,6 @@ test "read/write through global variable array of struct fields initialized via test "implicit cast single-item pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testImplicitCastSingleItemPtr(); @@ -303,7 +301,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 { test "comptime evaluating function that takes array by value" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const arr = [_]u8{ 1, 2 }; @@ -316,7 +313,6 @@ test "comptime evaluating function that takes array by value" { test "runtime initialize array elem and then implicit cast to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var two: i32 = 2; @@ -327,7 +323,6 @@ test "runtime initialize array elem and then implicit cast to slice" { test "array literal as argument to function" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -418,7 +413,6 @@ test "double nested array to const slice cast in array literal" { test "anonymous literal in array" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -444,7 +438,6 @@ test "anonymous literal in array" { test "access the null element of a null terminated array" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -462,7 +455,6 @@ test "access the null element of a null terminated array" { test "type deduction for array subscript expression" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { -- cgit v1.2.3 From 97c25fb8d049ebcced9f29241516c51e480fb8a0 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 17 Feb 2022 18:10:02 +0100 Subject: x64: implement array_elem_val when array is stored in memory --- src/arch/x86_64/CodeGen.zig | 106 +++++++++++++++++++------------------------- test/behavior/array.zig | 8 ++-- 2 files changed, 50 insertions(+), 64 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index cc3953e57b..6b27627825 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1604,6 +1604,12 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { .stack_offset => |off| { break :inner off; }, + .memory, + .got_load, + .direct_load, + => { + break :blk try self.loadMemPtrIntoRegister(Type.usize, array); + }, else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), } }; @@ -1845,6 +1851,42 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } +fn loadMemPtrIntoRegister(self: *Self, ptr_ty: Type, ptr: MCValue) InnerError!Register { + switch (ptr) { + .got_load, + .direct_load, + => |sym_index| { + const flags: u2 = switch (ptr) { + .got_load => 0b00, + .direct_load => 0b01, + else => unreachable, + }; + const reg = try self.register_manager.allocReg(null); + _ = try self.addInst(.{ + .tag = .lea_pie, + .ops = (Mir.Ops{ + .reg1 = reg.to64(), + .flags = flags, + }).encode(), + .data = .{ + .load_reloc = .{ + .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, + .sym_index = sym_index, + }, + }, + }); + return reg.to64(); + }, + .memory => |addr| { + // TODO: in case the address fits in an imm32 we can use [ds:imm32] + // instead of wasting an instruction copying the address to a register + const reg = try self.copyToTmpRegister(ptr_ty, .{ .immediate = addr }); + return reg.to64(); + }, + else => unreachable, + } +} + fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { _ = ptr_ty; const abi_size = value_ty.abiSize(self.target.*); @@ -1955,41 +1997,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type value.freezeIfRegister(&self.register_manager); defer value.unfreezeIfRegister(&self.register_manager); - const addr_reg: Register = blk: { - switch (ptr) { - .got_load, - .direct_load, - => |sym_index| { - const flags: u2 = switch (ptr) { - .got_load => 0b00, - .direct_load => 0b01, - else => unreachable, - }; - const addr_reg = try self.register_manager.allocReg(null); - _ = try self.addInst(.{ - .tag = .lea_pie, - .ops = (Mir.Ops{ - .reg1 = addr_reg.to64(), - .flags = flags, - }).encode(), - .data = .{ - .load_reloc = .{ - .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, - .sym_index = sym_index, - }, - }, - }); - break :blk addr_reg; - }, - .memory => |addr| { - // TODO: in case the address fits in an imm32 we can use [ds:imm32] - // instead of wasting an instruction copying the address to a register - const addr_reg = try self.copyToTmpRegister(ptr_ty, .{ .immediate = addr }); - break :blk addr_reg; - }, - else => unreachable, - } - }; + const addr_reg = try self.loadMemPtrIntoRegister(ptr_ty, ptr); // to get the actual address of the value we want to modify we have to go through the GOT // mov reg, [reg] @@ -3831,33 +3839,11 @@ fn genInlineMemcpy(self: *Self, stack_offset: i32, stack_reg: Register, ty: Type const addr_reg: Register = blk: { switch (val) { - .memory => |addr| { - const reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = addr }); - break :blk reg; - }, + .memory, .direct_load, .got_load, - => |sym_index| { - const flags: u2 = switch (val) { - .got_load => 0b00, - .direct_load => 0b01, - else => unreachable, - }; - const addr_reg = (try self.register_manager.allocReg(null)).to64(); - _ = try self.addInst(.{ - .tag = .lea_pie, - .ops = (Mir.Ops{ - .reg1 = addr_reg, - .flags = flags, - }).encode(), - .data = .{ - .load_reloc = .{ - .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, - .sym_index = sym_index, - }, - }, - }); - break :blk addr_reg; + => { + break :blk try self.loadMemPtrIntoRegister(Type.usize, val); }, .stack_offset => |off| { const addr_reg = (try self.register_manager.allocReg(null)).to64(); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index b4a4c37d95..ba478fef93 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -153,7 +153,7 @@ test "void arrays" { test "nested arrays" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const array_of_strings = [_][]const u8{ "hello", "this", "is", "my", "thing" }; for (array_of_strings) |s, i| { @@ -525,8 +525,8 @@ test "zero-sized array with recursive type definition" { test "type coercion of anon struct literal to array" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { const U = union { @@ -543,8 +543,8 @@ test "type coercion of anon struct literal to array" { try expect(arr1[1] == 56); try expect(arr1[2] == 54); - if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO - if (@import("builtin").zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO var x2: U = .{ .a = 42 }; const t2 = .{ x2, .{ .b = true }, .{ .c = "hello" } }; -- cgit v1.2.3 From 25e4b16e25502ca5e76e4049ed9f727168782dde Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 22 Feb 2022 14:15:09 +0100 Subject: Port more behavior tests --- test/behavior.zig | 220 ++++++++++----------- test/behavior/align.zig | 6 - test/behavior/array.zig | 10 +- test/behavior/basic.zig | 6 - test/behavior/bugs/1076.zig | 5 + test/behavior/bugs/1442.zig | 3 + test/behavior/bugs/2692.zig | 5 + test/behavior/bugs/2889.zig | 5 + test/behavior/bugs/3046.zig | 6 +- test/behavior/bugs/3586.zig | 5 + test/behavior/bugs/4560.zig | 4 + test/behavior/bugs/4954.zig | 6 + test/behavior/bugs/624.zig | 4 + test/behavior/bugs/704.zig | 5 + test/behavior/byval_arg_var.zig | 5 + test/behavior/defer.zig | 13 ++ test/behavior/enum.zig | 110 +++++++++++ test/behavior/error.zig | 48 +++++ test/behavior/fn.zig | 71 +++++++ test/behavior/for.zig | 24 ++- test/behavior/generics.zig | 43 +++- test/behavior/if.zig | 20 ++ test/behavior/incomplete_struct_param_tld.zig | 3 + test/behavior/inttoptr.zig | 6 + test/behavior/member_func.zig | 6 + test/behavior/null.zig | 29 +++ test/behavior/pointers.zig | 19 ++ .../ref_var_in_if_after_if_2nd_switch_prong.zig | 5 + test/behavior/slice.zig | 1 - test/behavior/src.zig | 3 + test/behavior/struct.zig | 12 +- test/behavior/this.zig | 7 + test/behavior/try.zig | 14 +- test/behavior/type_info.zig | 11 ++ test/behavior/undefined.zig | 11 ++ test/behavior/underscore.zig | 5 + test/behavior/union.zig | 139 +++++++++++++ test/behavior/usingnamespace.zig | 19 ++ test/behavior/void.zig | 11 ++ test/behavior/while.zig | 47 +++++ 40 files changed, 832 insertions(+), 140 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/test/behavior.zig b/test/behavior.zig index 8dcc205ff3..a034cf4b37 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -9,12 +9,16 @@ test { _ = @import("behavior/bitcast.zig"); _ = @import("behavior/bitreverse.zig"); _ = @import("behavior/byteswap.zig"); + _ = @import("behavior/byval_arg_var.zig"); _ = @import("behavior/bool.zig"); _ = @import("behavior/bugs/394.zig"); + _ = @import("behavior/bugs/624.zig"); _ = @import("behavior/bugs/655.zig"); _ = @import("behavior/bugs/656.zig"); _ = @import("behavior/bugs/679.zig"); + _ = @import("behavior/bugs/704.zig"); _ = @import("behavior/bugs/1025.zig"); + _ = @import("behavior/bugs/1076.zig"); _ = @import("behavior/bugs/1111.zig"); _ = @import("behavior/bugs/1277.zig"); _ = @import("behavior/bugs/1310.zig"); @@ -27,149 +31,145 @@ test { _ = @import("behavior/bugs/2006.zig"); _ = @import("behavior/bugs/2346.zig"); _ = @import("behavior/bugs/2578.zig"); + _ = @import("behavior/bugs/2692.zig"); + _ = @import("behavior/bugs/2889.zig"); _ = @import("behavior/bugs/3007.zig"); + _ = @import("behavior/bugs/3046.zig"); _ = @import("behavior/bugs/3112.zig"); _ = @import("behavior/bugs/3367.zig"); + _ = @import("behavior/bugs/3586.zig"); + _ = @import("behavior/bugs/4560.zig"); + _ = @import("behavior/bugs/4769_a.zig"); + _ = @import("behavior/bugs/4769_b.zig"); + _ = @import("behavior/bugs/4954.zig"); _ = @import("behavior/bugs/6850.zig"); _ = @import("behavior/bugs/7250.zig"); + _ = @import("behavior/call.zig"); _ = @import("behavior/cast.zig"); _ = @import("behavior/comptime_memory.zig"); + _ = @import("behavior/defer.zig"); + _ = @import("behavior/enum.zig"); + _ = @import("behavior/error.zig"); + _ = @import("behavior/fn.zig"); _ = @import("behavior/fn_delegation.zig"); _ = @import("behavior/fn_in_struct_in_comptime.zig"); + _ = @import("behavior/for.zig"); + _ = @import("behavior/generics.zig"); _ = @import("behavior/hasdecl.zig"); _ = @import("behavior/hasfield.zig"); + _ = @import("behavior/if.zig"); + _ = @import("behavior/import.zig"); + _ = @import("behavior/incomplete_struct_param_tld.zig"); + _ = @import("behavior/int_div.zig"); + _ = @import("behavior/inttoptr.zig"); _ = @import("behavior/ir_block_deps.zig"); + _ = @import("behavior/member_func.zig"); _ = @import("behavior/namespace_depends_on_compile_var.zig"); + _ = @import("behavior/null.zig"); _ = @import("behavior/optional.zig"); _ = @import("behavior/prefetch.zig"); + _ = @import("behavior/pointers.zig"); _ = @import("behavior/pub_enum.zig"); + _ = @import("behavior/ptrcast.zig"); _ = @import("behavior/reflection.zig"); + _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); _ = @import("behavior/slice.zig"); _ = @import("behavior/slice_sentinel_comptime.zig"); _ = @import("behavior/struct.zig"); + _ = @import("behavior/src.zig"); + _ = @import("behavior/this.zig"); _ = @import("behavior/truncate.zig"); + _ = @import("behavior/try.zig"); _ = @import("behavior/tuple.zig"); _ = @import("behavior/type.zig"); + _ = @import("behavior/type_info.zig"); + _ = @import("behavior/undefined.zig"); + _ = @import("behavior/underscore.zig"); + _ = @import("behavior/union.zig"); + _ = @import("behavior/usingnamespace.zig"); _ = @import("behavior/var_args.zig"); - _ = @import("behavior/int_div.zig"); + _ = @import("behavior/void.zig"); + _ = @import("behavior/while.zig"); // tests that don't pass for stage1 if (builtin.zig_backend != .stage1) { _ = @import("behavior/decltest.zig"); } - if (builtin.zig_backend != .stage2_arm and builtin.zig_backend != .stage2_x86_64 and builtin.zig_backend != .stage2_aarch64) { - // Tests that pass (partly) for stage1, llvm backend, C backend, wasm backend. - _ = @import("behavior/bugs/624.zig"); - _ = @import("behavior/bugs/704.zig"); - _ = @import("behavior/bugs/1076.zig"); - _ = @import("behavior/bugs/2692.zig"); - _ = @import("behavior/bugs/2889.zig"); - _ = @import("behavior/bugs/3046.zig"); - _ = @import("behavior/bugs/3586.zig"); - _ = @import("behavior/bugs/4560.zig"); - _ = @import("behavior/bugs/4769_a.zig"); - _ = @import("behavior/bugs/4769_b.zig"); - _ = @import("behavior/bugs/4954.zig"); - _ = @import("behavior/byval_arg_var.zig"); - _ = @import("behavior/call.zig"); - _ = @import("behavior/defer.zig"); - _ = @import("behavior/enum.zig"); - _ = @import("behavior/error.zig"); - _ = @import("behavior/fn.zig"); - _ = @import("behavior/for.zig"); - _ = @import("behavior/generics.zig"); - _ = @import("behavior/if.zig"); - _ = @import("behavior/import.zig"); - _ = @import("behavior/incomplete_struct_param_tld.zig"); - _ = @import("behavior/inttoptr.zig"); - _ = @import("behavior/member_func.zig"); - _ = @import("behavior/null.zig"); - _ = @import("behavior/pointers.zig"); - _ = @import("behavior/ptrcast.zig"); - _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); - _ = @import("behavior/src.zig"); - _ = @import("behavior/this.zig"); - _ = @import("behavior/try.zig"); - _ = @import("behavior/type_info.zig"); - _ = @import("behavior/undefined.zig"); - _ = @import("behavior/underscore.zig"); - _ = @import("behavior/union.zig"); - _ = @import("behavior/usingnamespace.zig"); - _ = @import("behavior/void.zig"); - _ = @import("behavior/while.zig"); + if (builtin.zig_backend != .stage2_arm and + builtin.zig_backend != .stage2_x86_64 and + builtin.zig_backend != .stage2_aarch64 and + builtin.zig_backend != .stage2_wasm) + { + // Tests that pass for stage1, llvm backend, C backend + _ = @import("behavior/bugs/9584.zig"); + _ = @import("behavior/cast_int.zig"); + _ = @import("behavior/eval.zig"); + _ = @import("behavior/int128.zig"); + _ = @import("behavior/merge_error_sets.zig"); + _ = @import("behavior/translate_c_macros.zig"); - if (builtin.zig_backend != .stage2_wasm) { - // Tests that pass for stage1, llvm backend, C backend - _ = @import("behavior/bugs/9584.zig"); - _ = @import("behavior/cast_int.zig"); - _ = @import("behavior/eval.zig"); - _ = @import("behavior/int128.zig"); - _ = @import("behavior/merge_error_sets.zig"); - _ = @import("behavior/translate_c_macros.zig"); + if (builtin.zig_backend != .stage2_c) { + // Tests that pass for stage1 and the llvm backend. + _ = @import("behavior/atomics.zig"); + _ = @import("behavior/floatop.zig"); + _ = @import("behavior/math.zig"); + _ = @import("behavior/maximum_minimum.zig"); + _ = @import("behavior/popcount.zig"); + _ = @import("behavior/saturating_arithmetic.zig"); + _ = @import("behavior/sizeof_and_typeof.zig"); + _ = @import("behavior/switch.zig"); + _ = @import("behavior/widening.zig"); - if (builtin.zig_backend != .stage2_c) { - // Tests that pass for stage1 and the llvm backend. - _ = @import("behavior/atomics.zig"); - _ = @import("behavior/floatop.zig"); - _ = @import("behavior/math.zig"); - _ = @import("behavior/maximum_minimum.zig"); - _ = @import("behavior/popcount.zig"); - _ = @import("behavior/saturating_arithmetic.zig"); - _ = @import("behavior/sizeof_and_typeof.zig"); - _ = @import("behavior/switch.zig"); - _ = @import("behavior/widening.zig"); + if (builtin.zig_backend == .stage1) { + // Tests that only pass for the stage1 backend. + if (builtin.os.tag != .wasi) { + _ = @import("behavior/asm.zig"); + _ = @import("behavior/async_fn.zig"); + } + _ = @import("behavior/await_struct.zig"); + _ = @import("behavior/bugs/421.zig"); + _ = @import("behavior/bugs/529.zig"); + _ = @import("behavior/bugs/718.zig"); + _ = @import("behavior/bugs/726.zig"); + _ = @import("behavior/bugs/828.zig"); + _ = @import("behavior/bugs/920.zig"); + _ = @import("behavior/bugs/1120.zig"); + _ = @import("behavior/bugs/1421.zig"); _ = @import("behavior/bugs/1442.zig"); - - if (builtin.zig_backend == .stage1) { - // Tests that only pass for the stage1 backend. - if (builtin.os.tag != .wasi) { - _ = @import("behavior/asm.zig"); - _ = @import("behavior/async_fn.zig"); - } - _ = @import("behavior/await_struct.zig"); - _ = @import("behavior/bugs/421.zig"); - _ = @import("behavior/bugs/529.zig"); - _ = @import("behavior/bugs/718.zig"); - _ = @import("behavior/bugs/726.zig"); - _ = @import("behavior/bugs/828.zig"); - _ = @import("behavior/bugs/920.zig"); - _ = @import("behavior/bugs/1120.zig"); - _ = @import("behavior/bugs/1421.zig"); - _ = @import("behavior/bugs/1607.zig"); - _ = @import("behavior/bugs/1851.zig"); - _ = @import("behavior/bugs/2114.zig"); - _ = @import("behavior/bugs/3384.zig"); - _ = @import("behavior/bugs/3742.zig"); - _ = @import("behavior/bugs/3779.zig"); - _ = @import("behavior/bugs/4328.zig"); - _ = @import("behavior/bugs/5398.zig"); - _ = @import("behavior/bugs/5413.zig"); - _ = @import("behavior/bugs/5474.zig"); - _ = @import("behavior/bugs/5487.zig"); - _ = @import("behavior/bugs/6456.zig"); - _ = @import("behavior/bugs/6781.zig"); - _ = @import("behavior/bugs/7003.zig"); - _ = @import("behavior/bugs/7027.zig"); - _ = @import("behavior/bugs/7047.zig"); - _ = @import("behavior/bugs/10147.zig"); - _ = @import("behavior/const_slice_child.zig"); - _ = @import("behavior/export_self_referential_type_info.zig"); - _ = @import("behavior/field_parent_ptr.zig"); - _ = @import("behavior/misc.zig"); - _ = @import("behavior/muladd.zig"); - _ = @import("behavior/select.zig"); - _ = @import("behavior/shuffle.zig"); - _ = @import("behavior/struct_contains_null_ptr_itself.zig"); - _ = @import("behavior/struct_contains_slice_of_itself.zig"); - _ = @import("behavior/switch_prong_err_enum.zig"); - _ = @import("behavior/switch_prong_implicit_cast.zig"); - _ = @import("behavior/typename.zig"); - _ = @import("behavior/union_with_members.zig"); - _ = @import("behavior/vector.zig"); - if (builtin.target.cpu.arch == .wasm32) { - _ = @import("behavior/wasm.zig"); - } + _ = @import("behavior/bugs/1607.zig"); + _ = @import("behavior/bugs/1851.zig"); + _ = @import("behavior/bugs/2114.zig"); + _ = @import("behavior/bugs/3384.zig"); + _ = @import("behavior/bugs/3742.zig"); + _ = @import("behavior/bugs/3779.zig"); + _ = @import("behavior/bugs/4328.zig"); + _ = @import("behavior/bugs/5398.zig"); + _ = @import("behavior/bugs/5413.zig"); + _ = @import("behavior/bugs/5474.zig"); + _ = @import("behavior/bugs/5487.zig"); + _ = @import("behavior/bugs/6456.zig"); + _ = @import("behavior/bugs/6781.zig"); + _ = @import("behavior/bugs/7003.zig"); + _ = @import("behavior/bugs/7027.zig"); + _ = @import("behavior/bugs/7047.zig"); + _ = @import("behavior/bugs/10147.zig"); + _ = @import("behavior/const_slice_child.zig"); + _ = @import("behavior/export_self_referential_type_info.zig"); + _ = @import("behavior/field_parent_ptr.zig"); + _ = @import("behavior/misc.zig"); + _ = @import("behavior/muladd.zig"); + _ = @import("behavior/select.zig"); + _ = @import("behavior/shuffle.zig"); + _ = @import("behavior/struct_contains_null_ptr_itself.zig"); + _ = @import("behavior/struct_contains_slice_of_itself.zig"); + _ = @import("behavior/switch_prong_err_enum.zig"); + _ = @import("behavior/switch_prong_implicit_cast.zig"); + _ = @import("behavior/typename.zig"); + _ = @import("behavior/union_with_members.zig"); + _ = @import("behavior/vector.zig"); + if (builtin.target.cpu.arch == .wasm32) { + _ = @import("behavior/wasm.zig"); } } } diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 6a899fcdc5..5518d40756 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -180,8 +180,6 @@ fn noop4() align(4) void {} test "function alignment" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // function alignment is a compile error on wasm32/wasm64 @@ -199,7 +197,6 @@ test "implicitly decreasing fn alignment" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -226,8 +223,6 @@ test "@alignCast functions" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // function alignment is a compile error on wasm32/wasm64 @@ -250,7 +245,6 @@ test "generic function with align param" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; diff --git a/test/behavior/array.zig b/test/behavior/array.zig index ba478fef93..0bbdad44c4 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -49,7 +49,7 @@ fn getArrayLen(a: []const u32) usize { test "array init with mult" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const a = 'a'; var i: [8]u8 = [2]u8{ a, 'b' } ** 4; @@ -112,7 +112,7 @@ test "array len field" { test "array with sentinels" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest(is_ct: bool) !void { @@ -179,7 +179,8 @@ fn plusOne(x: u32) u32 { test "single-item pointer to array indexing and slicing" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try testSingleItemPtrArrayIndexSlice(); comptime try testSingleItemPtrArrayIndexSlice(); @@ -205,7 +206,8 @@ fn doSomeMangling(array: *[4]u8) void { test "implicit cast zero sized array ptr to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; { var b = "".*; diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index d5081ca636..6c0fbd028a 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -117,7 +117,6 @@ fn first4KeysOfHomeRow() []const u8 { test "return string from function" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; try expect(mem.eql(u8, first4KeysOfHomeRow(), "aoeu")); } @@ -231,7 +230,6 @@ test "compile time global reinterpret" { test "cast undefined" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const array: [100]u8 = undefined; const slice = @as([]const u8, &array); @@ -303,7 +301,6 @@ test "call function pointer in struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage1) return error.SkipZigTest; try expect(mem.eql(u8, f3(true), "a")); @@ -382,7 +379,6 @@ fn testMemcpyMemset() !void { test "variable is allowed to be a pointer to an opaque type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO var x: i32 = 1234; @@ -425,7 +421,6 @@ test "array 2D const double ptr" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO const rect_2d_vertexes = [_][1]f32{ @@ -476,7 +471,6 @@ fn testArray2DConstDoublePtr(ptr: *const f32) !void { test "double implicit cast in same expression" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var x = @as(i32, @as(u16, nine())); try expect(x == 9); diff --git a/test/behavior/bugs/1076.zig b/test/behavior/bugs/1076.zig index ab7d468a7b..6bf38eb617 100644 --- a/test/behavior/bugs/1076.zig +++ b/test/behavior/bugs/1076.zig @@ -1,8 +1,13 @@ const std = @import("std"); +const builtin = @import("builtin"); const mem = std.mem; const expect = std.testing.expect; test "comptime code should not modify constant data" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testCastPtrOfArrayToSliceAndPtr(); comptime try testCastPtrOfArrayToSliceAndPtr(); } diff --git a/test/behavior/bugs/1442.zig b/test/behavior/bugs/1442.zig index 5298d34acb..f0d524006c 100644 --- a/test/behavior/bugs/1442.zig +++ b/test/behavior/bugs/1442.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const Union = union(enum) { Text: []const u8, @@ -6,6 +7,8 @@ const Union = union(enum) { }; test "const error union field alignment" { + if (builtin.zig_backend != .stage1) return error.SkipZigTest; + var union_or_err: anyerror!Union = Union{ .Color = 1234 }; try std.testing.expect((union_or_err catch unreachable).Color == 1234); } diff --git a/test/behavior/bugs/2692.zig b/test/behavior/bugs/2692.zig index 1bc38a0274..0692c51b8c 100644 --- a/test/behavior/bugs/2692.zig +++ b/test/behavior/bugs/2692.zig @@ -1,8 +1,13 @@ +const builtin = @import("builtin"); + fn foo(a: []u8) void { _ = a; } test "address of 0 length array" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var pt: [0]u8 = undefined; foo(&pt); } diff --git a/test/behavior/bugs/2889.zig b/test/behavior/bugs/2889.zig index 473f6c615d..8bb70cb198 100644 --- a/test/behavior/bugs/2889.zig +++ b/test/behavior/bugs/2889.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const source = "A-"; @@ -26,6 +27,10 @@ fn parseNote() ?i32 { } test "fixed" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const result = parseNote(); try std.testing.expect(result.? == 9); } diff --git a/test/behavior/bugs/3046.zig b/test/behavior/bugs/3046.zig index 71e937f244..dc18256d33 100644 --- a/test/behavior/bugs/3046.zig +++ b/test/behavior/bugs/3046.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const expect = std.testing.expect; const SomeStruct = struct { @@ -12,7 +13,10 @@ fn couldFail() anyerror!i32 { var some_struct: SomeStruct = undefined; test "fixed" { - if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; some_struct = SomeStruct{ .field = couldFail() catch @as(i32, 0), diff --git a/test/behavior/bugs/3586.zig b/test/behavior/bugs/3586.zig index 047cb5d205..f7266e9918 100644 --- a/test/behavior/bugs/3586.zig +++ b/test/behavior/bugs/3586.zig @@ -1,3 +1,5 @@ +const builtin = @import("builtin"); + const NoteParams = struct {}; const Container = struct { @@ -5,6 +7,9 @@ const Container = struct { }; test "fixed" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var ctr = Container{ .params = NoteParams{}, }; diff --git a/test/behavior/bugs/4560.zig b/test/behavior/bugs/4560.zig index 3119bd99b9..b3e40dd7f8 100644 --- a/test/behavior/bugs/4560.zig +++ b/test/behavior/bugs/4560.zig @@ -1,6 +1,10 @@ const std = @import("std"); +const builtin = @import("builtin"); test "fixed" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var s: S = .{ .a = 1, .b = .{ diff --git a/test/behavior/bugs/4954.zig b/test/behavior/bugs/4954.zig index 3dea934895..eaae4d8ba2 100644 --- a/test/behavior/bugs/4954.zig +++ b/test/behavior/bugs/4954.zig @@ -1,8 +1,14 @@ +const builtin = @import("builtin"); + fn f(buf: []u8) void { _ = &buf[@sizeOf(u32)]; } test "crash" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var buf: [4096]u8 = undefined; f(&buf); } diff --git a/test/behavior/bugs/624.zig b/test/behavior/bugs/624.zig index b8bf09f22e..b5288ebe17 100644 --- a/test/behavior/bugs/624.zig +++ b/test/behavior/bugs/624.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const expect = std.testing.expect; const TestContext = struct { @@ -19,6 +20,9 @@ fn MemoryPool(comptime T: type) type { } test "foo" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var allocator = ContextAllocator{ .n = 10 }; try expect(allocator.n == 10); } diff --git a/test/behavior/bugs/704.zig b/test/behavior/bugs/704.zig index 15fe9419a6..352f61ac62 100644 --- a/test/behavior/bugs/704.zig +++ b/test/behavior/bugs/704.zig @@ -1,9 +1,14 @@ +const builtin = @import("builtin"); + const xxx = struct { pub fn bar(self: *xxx) void { _ = self; } }; test "bug 704" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var x: xxx = undefined; x.bar(); } diff --git a/test/behavior/byval_arg_var.zig b/test/behavior/byval_arg_var.zig index a46a9ed0b2..3a1be9cc0c 100644 --- a/test/behavior/byval_arg_var.zig +++ b/test/behavior/byval_arg_var.zig @@ -1,8 +1,13 @@ const std = @import("std"); +const builtin = @import("builtin"); var result: []const u8 = "wrong"; test "pass string literal byvalue to a generic var param" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + start(); blowUpStack(10); diff --git a/test/behavior/defer.zig b/test/behavior/defer.zig index b574b25ce5..a9d363ddd1 100644 --- a/test/behavior/defer.zig +++ b/test/behavior/defer.zig @@ -5,6 +5,9 @@ const expectEqual = std.testing.expectEqual; const expectError = std.testing.expectError; test "break and continue inside loop inside defer expression" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + testBreakContInDefer(10); comptime testBreakContInDefer(10); } @@ -21,6 +24,9 @@ fn testBreakContInDefer(x: usize) void { } test "defer and labeled break" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var i = @as(usize, 0); blk: { @@ -32,6 +38,9 @@ test "defer and labeled break" { } test "errdefer does not apply to fn inside fn" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (testNestedFnErrDefer()) |_| @panic("expected error") else |e| try expect(e == error.Bad); } @@ -47,6 +56,10 @@ fn testNestedFnErrDefer() anyerror!void { } test "return variable while defer expression in scope to modify it" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn doTheTest() !void { try expect(notNull().? == 1); diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 9dd19d8f2e..48f4019c73 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -11,6 +11,9 @@ fn shouldEqual(n: Number, expected: u3) !void { } test "enum to int" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try shouldEqual(Number.Zero, 0); try shouldEqual(Number.One, 1); try shouldEqual(Number.Two, 2); @@ -24,6 +27,9 @@ fn testIntToEnumEval(x: i32) !void { const IntToEnumNumber = enum { Zero, One, Two, Three, Four }; test "int to enum" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testIntToEnumEval(3); } @@ -553,6 +559,9 @@ const ValueCount257 = enum { }; test "enum sizes" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + comptime { try expect(@sizeOf(ValueCount1) == 0); try expect(@sizeOf(ValueCount2) == 1); @@ -562,6 +571,9 @@ test "enum sizes" { } test "enum literal equality" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const x = .hi; const y = .ok; const z = .hi; @@ -571,6 +583,9 @@ test "enum literal equality" { } test "enum literal cast to enum" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Color = enum { Auto, Off, On }; var color1: Color = .Auto; @@ -579,6 +594,9 @@ test "enum literal cast to enum" { } test "peer type resolution with enum literal" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Items = enum { one, two }; try expect(Items.two == .two); @@ -603,11 +621,19 @@ fn testEnumWithSpecifiedTagValues(x: MultipleChoice) !void { } test "enum with specified tag values" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testEnumWithSpecifiedTagValues(MultipleChoice.C); comptime try testEnumWithSpecifiedTagValues(MultipleChoice.C); } test "non-exhaustive enum" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { const E = enum(u8) { a, b, _ }; @@ -649,6 +675,9 @@ test "non-exhaustive enum" { } test "empty non-exhaustive enum" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { const E = enum(u8) { _ }; @@ -668,6 +697,10 @@ test "empty non-exhaustive enum" { } test "single field non-exhaustive enum" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { const E = enum(u8) { a, _ }; fn doTheTest(y: u8) !void { @@ -708,6 +741,9 @@ const EnumWithTagValues = enum(u4) { D = 1 << 3, }; test "enum with tag values don't require parens" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(@enumToInt(EnumWithTagValues.C) == 0b0100); } @@ -724,11 +760,18 @@ const MultipleChoice2 = enum(u32) { }; test "cast integer literal to enum" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(@intToEnum(MultipleChoice2, 0) == MultipleChoice2.Unspecified1); try expect(@intToEnum(MultipleChoice2, 40) == MultipleChoice2.B); } test "enum with specified and unspecified tag values" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D); comptime try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D); } @@ -752,6 +795,9 @@ const Small2 = enum(u2) { One, Two }; const Small = enum(u2) { One, Two, Three, Four }; test "set enum tag type" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + { var x = Small.One; x = Small.Two; @@ -765,6 +811,9 @@ test "set enum tag type" { } test "casting enum to its tag type" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testCastEnumTag(Small2.Two); comptime try testCastEnumTag(Small2.Two); } @@ -774,6 +823,9 @@ fn testCastEnumTag(value: Small2) !void { } test "enum with 1 field but explicit tag type should still have the tag type" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Enum = enum(u8) { B = 2, }; @@ -781,6 +833,9 @@ test "enum with 1 field but explicit tag type should still have the tag type" { } test "signed integer as enum tag" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const SignedEnum = enum(i2) { A0 = -1, A1 = 0, @@ -793,6 +848,9 @@ test "signed integer as enum tag" { } test "enum with one member and custom tag type" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const E = enum(u2) { One, }; @@ -804,6 +862,9 @@ test "enum with one member and custom tag type" { } test "enum with one member and u1 tag type @enumToInt" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Enum = enum(u1) { Test, }; @@ -811,6 +872,9 @@ test "enum with one member and u1 tag type @enumToInt" { } test "enum with comptime_int tag type" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Enum = enum(comptime_int) { One = 3, Two = 2, @@ -820,6 +884,9 @@ test "enum with comptime_int tag type" { } test "enum with one member default to u0 tag type" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const E0 = enum { X }; comptime try expect(Tag(E0) == u0); } @@ -836,11 +903,17 @@ fn doALoopThing(id: EnumWithOneMember) void { } test "comparison operator on enum with one member is comptime known" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + doALoopThing(EnumWithOneMember.Eof); } const State = enum { Start }; test "switch on enum with one member is comptime known" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var state = State.Start; switch (state) { State.Start => return, @@ -849,6 +922,9 @@ test "switch on enum with one member is comptime known" { } test "method call on an enum" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { const E = enum { one, @@ -885,6 +961,10 @@ test "enum value allocation" { } test "enum literal casting to tagged union" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Arch = union(enum) { x86_64, arm: Arm32, @@ -930,6 +1010,11 @@ test "exporting enum type and value" { } test "constant enum initialization with differing sizes" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + try test3_1(test3_foo); try test3_2(test3_bar); } @@ -970,6 +1055,9 @@ fn test3_2(f: Test3Foo) !void { test "@tagName" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); comptime try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); @@ -984,6 +1072,9 @@ const BareNumber = enum { One, Two, Three }; test "@tagName non-exhaustive enum" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B")); comptime try expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B")); @@ -993,6 +1084,9 @@ const NonExhaustive = enum(u8) { A, B, _ }; test "@tagName is null-terminated" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const S = struct { fn doTheTest(n: BareNumber) !void { @@ -1006,6 +1100,9 @@ test "@tagName is null-terminated" { test "tag name with assigned enum values" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const LocalFoo = enum(u8) { A = 1, @@ -1016,11 +1113,18 @@ test "tag name with assigned enum values" { } test "@tagName on enum literals" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(mem.eql(u8, @tagName(.FooBar), "FooBar")); comptime try expect(mem.eql(u8, @tagName(.FooBar), "FooBar")); } test "enum literal casting to optional" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var bar: ?Bar = undefined; bar = .B; @@ -1045,6 +1149,9 @@ const bit_field_1 = BitFieldOfEnums{ test "bit field access with enum fields" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var data = bit_field_1; try expect(getA(&data) == A.Two); @@ -1073,6 +1180,9 @@ fn getC(data: *const BitFieldOfEnums) C { } test "enum literal in array literal" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Items = enum { one, two }; const array = [_]Items{ .one, .two }; diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 2e243d1d23..028bd26047 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -6,12 +6,18 @@ const expectEqual = std.testing.expectEqual; const mem = std.mem; test "error values" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const a = @errorToInt(error.err1); const b = @errorToInt(error.err2); try expect(a != b); } test "redefinition of error values allowed" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + shouldBeNotEqual(error.AnError, error.SecondError); } fn shouldBeNotEqual(a: anyerror, b: anyerror) void { @@ -19,6 +25,10 @@ fn shouldBeNotEqual(a: anyerror, b: anyerror) void { } test "error binary operator" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const a = errBinaryOperatorG(true) catch 3; const b = errBinaryOperatorG(false) catch 3; try expect(a == 3); @@ -29,6 +39,9 @@ fn errBinaryOperatorG(x: bool) anyerror!isize { } test "empty error union" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const x = error{} || error{}; _ = x; } @@ -48,10 +61,18 @@ pub fn baz() anyerror!i32 { } test "error wrapping" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect((baz() catch unreachable) == 15); } test "unwrap simple value from error" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const i = unwrapSimpleValueFromErrorDo() catch unreachable; try expect(i == 13); } @@ -60,6 +81,10 @@ fn unwrapSimpleValueFromErrorDo() anyerror!isize { } test "error return in assignment" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + doErrReturnInAssignment() catch unreachable; } @@ -73,12 +98,19 @@ fn makeANonErr() anyerror!i32 { } test "syntax: optional operator in front of error union operator" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + comptime { try expect(?(anyerror!i32) == ?(anyerror!i32)); } } test "widen cast integer payload of error union function call" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn errorable() !u64 { var x = @as(u64, try number()); @@ -93,12 +125,19 @@ test "widen cast integer payload of error union function call" { } test "debug info for optional error set" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const SomeError = error{Hello}; var a_local_variable: ?SomeError = null; _ = a_local_variable; } test "implicit cast to optional to error union to return result loc" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn entry() !void { var x: Foo = undefined; @@ -118,6 +157,9 @@ test "implicit cast to optional to error union to return result loc" { } test "error: fn returning empty error set can be passed as fn returning any error" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + entry(); comptime entry(); } @@ -482,6 +524,9 @@ test "error union comptime caching" { test "@errorName" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(mem.eql(u8, @errorName(error.AnError), "AnError")); try expect(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName")); @@ -494,6 +539,9 @@ fn gimmeItBroke() anyerror { test "@errorName sentinel length matches slice length" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const name = testBuiltinErrorName(error.FooBar); const length: usize = 6; diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index 17a3d9a93b..c4779379c5 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -5,6 +5,9 @@ const expect = testing.expect; const expectEqual = testing.expectEqual; test "params" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(testParamsAdd(22, 11) == 33); } fn testParamsAdd(a: i32, b: i32) i32 { @@ -12,6 +15,9 @@ fn testParamsAdd(a: i32, b: i32) i32 { } test "local variables" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + testLocVars(2); } fn testLocVars(b: i32) void { @@ -20,6 +26,9 @@ fn testLocVars(b: i32) void { } test "mutable local variables" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var zero: i32 = 0; try expect(zero == 0); @@ -31,6 +40,9 @@ test "mutable local variables" { } test "separate block scopes" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + { const no_conflict: i32 = 5; try expect(no_conflict == 5); @@ -47,10 +59,16 @@ fn @"weird function name"() i32 { return 1234; } test "weird function name" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(@"weird function name"() == 1234); } test "assign inline fn to const variable" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const a = inlineFn; a(); } @@ -68,6 +86,9 @@ fn outer(y: u32) *const fn (u32) u32 { } test "return inner function which references comptime variable of outer function" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage1) return error.SkipZigTest; var func = outer(10); @@ -76,6 +97,9 @@ test "return inner function which references comptime variable of outer function test "discard the result of a function that returns a struct" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn entry() void { _ = func(); @@ -97,6 +121,9 @@ test "discard the result of a function that returns a struct" { test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage1) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const S = struct { field: u32, @@ -129,6 +156,9 @@ test "inline function call that calls optional function pointer, return pointer } test "implicit cast function unreachable return" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + wantsFnWithVoid(fnWithUnreachable); } @@ -143,6 +173,8 @@ fn fnWithUnreachable() noreturn { test "extern struct with stdcallcc fn pointer" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage1) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const S = extern struct { ptr: *const fn () callconv(if (builtin.target.cpu.arch == .i386) .Stdcall else .C) i32, @@ -170,10 +202,16 @@ fn fComplexCallconvRet(x: u32) callconv(blk: { } test "function with complex callconv and return type expressions" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(fComplexCallconvRet(3).x == 9); } test "pass by non-copying value" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3); } @@ -187,6 +225,10 @@ fn addPointCoords(pt: Point) i32 { } test "pass by non-copying value through var arg" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect((try addPointCoordsVar(Point{ .x = 1, .y = 2 })) == 3); } @@ -196,6 +238,9 @@ fn addPointCoordsVar(pt: anytype) !i32 { } test "pass by non-copying value as method" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var pt = Point2{ .x = 1, .y = 2 }; try expect(pt.addPointCoords() == 3); } @@ -210,6 +255,9 @@ const Point2 = struct { }; test "pass by non-copying value as method, which is generic" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var pt = Point3{ .x = 1, .y = 2 }; try expect(pt.addPointCoords(i32) == 3); } @@ -225,6 +273,9 @@ const Point3 = struct { }; test "pass by non-copying value as method, at comptime" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + comptime { var pt = Point2{ .x = 1, .y = 2 }; try expect(pt.addPointCoords() == 3); @@ -232,6 +283,9 @@ test "pass by non-copying value as method, at comptime" { } test "implicit cast fn call result to optional in field result" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn entry() !void { var x = Foo{ @@ -255,6 +309,10 @@ test "implicit cast fn call result to optional in field result" { } test "void parameters" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO try voidFun(1, void{}, 2, {}); } @@ -267,6 +325,9 @@ fn voidFun(a: i32, b: void, c: i32, d: void) !void { } test "call function with empty string" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + acceptsString(""); } @@ -301,6 +362,9 @@ fn fn4() u32 { } test "number literal as an argument" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try numberLiteralArg(3); comptime try numberLiteralArg(3); } @@ -311,6 +375,10 @@ fn numberLiteralArg(a: anytype) !void { test "function call with anon list literal" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn doTheTest() !void { try consumeVec(.{ 9, 8, 7 }); @@ -327,6 +395,9 @@ test "function call with anon list literal" { } test "ability to give comptime types and non comptime types to same parameter" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn doTheTest() !void { var x: i32 = 1; diff --git a/test/behavior/for.zig b/test/behavior/for.zig index 2ec5a74d73..011363bffd 100644 --- a/test/behavior/for.zig +++ b/test/behavior/for.zig @@ -5,6 +5,9 @@ const expectEqual = std.testing.expectEqual; const mem = std.mem; test "continue in for loop" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const array = [_]i32{ 1, 2, 3, 4, 5 }; var sum: i32 = 0; for (array) |x| { @@ -18,6 +21,9 @@ test "continue in for loop" { } test "break from outer for loop" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testBreakOuter(); comptime try testBreakOuter(); } @@ -35,6 +41,9 @@ fn testBreakOuter() !void { } test "continue outer for loop" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testContinueOuter(); comptime try testContinueOuter(); } @@ -52,6 +61,9 @@ fn testContinueOuter() !void { } test "ignore lval with underscore (for loop)" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + for ([_]void{}) |_, i| { _ = i; for ([_]void{}) |_, j| { @@ -63,7 +75,10 @@ test "ignore lval with underscore (for loop)" { } test "basic for loop" { - if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const expected_result = [_]u8{ 9, 8, 7, 6, 0, 1, 2, 3 } ** 3; @@ -104,6 +119,10 @@ test "basic for loop" { } test "for with null and T peer types and inferred result location type" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn doTheTest(slice: []const u8) !void { if (for (slice) |item| { @@ -121,6 +140,9 @@ test "for with null and T peer types and inferred result location type" { } test "2 break statements and an else" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn entry(t: bool, f: bool) !void { var buf: [10]u8 = undefined; diff --git a/test/behavior/generics.zig b/test/behavior/generics.zig index 1942e82340..e76cca4e1f 100644 --- a/test/behavior/generics.zig +++ b/test/behavior/generics.zig @@ -5,6 +5,9 @@ const expect = testing.expect; const expectEqual = testing.expectEqual; test "one param, explicit comptime" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var x: usize = 0; x += checkSize(i32); x += checkSize(bool); @@ -17,6 +20,9 @@ fn checkSize(comptime T: type) usize { } test "simple generic fn" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(max(i32, 3, -1) == 3); try expect(max(u8, 1, 100) == 100); if (builtin.zig_backend == .stage1) { @@ -37,6 +43,9 @@ fn add(comptime a: i32, b: i32) i32 { const the_max = max(u32, 1234, 5678); test "compile time generic eval" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(the_max == 5678); } @@ -53,12 +62,20 @@ fn sameButWithFloats(a: f64, b: f64) f64 { } test "fn with comptime args" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(gimmeTheBigOne(1234, 5678) == 5678); try expect(shouldCallSameInstance(34, 12) == 34); try expect(sameButWithFloats(0.43, 0.49) == 0.49); } test "anytype params" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(max_i32(12, 34) == 34); try expect(max_f64(1.2, 3.4) == 3.4); comptime { @@ -80,6 +97,10 @@ fn max_f64(a: f64, b: f64) f64 { } test "type constructed by comptime function call" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var l: SimpleList(10) = undefined; l.array[0] = 10; l.array[1] = 11; @@ -99,6 +120,9 @@ fn SimpleList(comptime L: usize) type { } test "function with return type type" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var list: List(i32) = undefined; var list2: List(i32) = undefined; list.length = 10; @@ -120,6 +144,9 @@ pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) type { } test "const decls in struct" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(GenericDataThing(3).count_plus_one == 4); } fn GenericDataThing(comptime count: isize) type { @@ -129,6 +156,9 @@ fn GenericDataThing(comptime count: isize) type { } test "use generic param in generic param" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(aGenericFn(i32, 3, 4) == 7); } fn aGenericFn(comptime T: type, comptime a: T, b: T) T { @@ -136,6 +166,9 @@ fn aGenericFn(comptime T: type, comptime a: T, b: T) T { } test "generic fn with implicit cast" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(getFirstByte(u8, &[_]u8{13}) == 13); try expect(getFirstByte(u16, &[_]u16{ 0, @@ -150,6 +183,9 @@ fn getFirstByte(comptime T: type, mem: []const T) u8 { } test "generic fn keeps non-generic parameter types" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const A = 128; const S = struct { @@ -165,8 +201,10 @@ test "generic fn keeps non-generic parameter types" { } test "array of generic fns" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + try expect(foos[0](true)); try expect(!foos[1](true)); } @@ -185,7 +223,8 @@ fn foo2(arg: anytype) bool { test "generic struct" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var a1 = GenNode(i32){ .value = 13, .next = null, diff --git a/test/behavior/if.zig b/test/behavior/if.zig index 7f80229332..068f3bdd21 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -4,6 +4,9 @@ const expect = std.testing.expect; const expectEqual = std.testing.expectEqual; test "if statements" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + shouldBeEqual(1, 1); firstEqlThird(2, 1, 2); } @@ -27,6 +30,9 @@ fn firstEqlThird(a: i32, b: i32, c: i32) void { } test "else if expression" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(elseIfExpressionF(1) == 1); } fn elseIfExpressionF(c: u8) u8 { @@ -44,6 +50,10 @@ var global_with_val: anyerror!u32 = 0; var global_with_err: anyerror!u32 = error.SomeError; test "unwrap mutable global var" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (global_with_val) |v| { try expect(v == 0); } else |_| { @@ -57,6 +67,9 @@ test "unwrap mutable global var" { } test "labeled break inside comptime if inside runtime if" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var answer: i32 = 0; var c = true; if (c) { @@ -68,6 +81,9 @@ test "labeled break inside comptime if inside runtime if" { } test "const result loc, runtime if cond, else unreachable" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Num = enum { One, Two }; var t = true; @@ -76,6 +92,10 @@ test "const result loc, runtime if cond, else unreachable" { } test "if copies its payload" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn doTheTest() !void { var tmp: ?i32 = 10; diff --git a/test/behavior/incomplete_struct_param_tld.zig b/test/behavior/incomplete_struct_param_tld.zig index a1e0672c7b..3f69c1cbbd 100644 --- a/test/behavior/incomplete_struct_param_tld.zig +++ b/test/behavior/incomplete_struct_param_tld.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const expect = @import("std").testing.expect; const A = struct { @@ -21,6 +22,8 @@ fn foo(a: A) i32 { } test "incomplete struct param top level declaration" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const a = A{ .b = B{ .c = C{ .x = 13 }, diff --git a/test/behavior/inttoptr.zig b/test/behavior/inttoptr.zig index 5c1acf51cd..8a642d7803 100644 --- a/test/behavior/inttoptr.zig +++ b/test/behavior/inttoptr.zig @@ -3,6 +3,8 @@ const builtin = @import("builtin"); test "casting integer address to function pointer" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; addressToFunction(); comptime addressToFunction(); @@ -14,6 +16,10 @@ fn addressToFunction() void { } test "mutate through ptr initialized with constant intToPtr value" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + forceCompilerAnalyzeBranchHardCodedPtrDereference(false); } diff --git a/test/behavior/member_func.zig b/test/behavior/member_func.zig index 3e4895e729..61280a6b11 100644 --- a/test/behavior/member_func.zig +++ b/test/behavior/member_func.zig @@ -28,6 +28,9 @@ const HasFuncs = struct { test "standard field calls" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(HasFuncs.one(0) == 1); try expect(HasFuncs.two(0) == 2); @@ -69,6 +72,9 @@ test "standard field calls" { test "@field field calls" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(@field(HasFuncs, "one")(0) == 1); try expect(@field(HasFuncs, "two")(0) == 2); diff --git a/test/behavior/null.zig b/test/behavior/null.zig index 35ecafff80..43c9355f3c 100644 --- a/test/behavior/null.zig +++ b/test/behavior/null.zig @@ -29,6 +29,10 @@ test "optional type" { } test "test maybe object and get a pointer to the inner value" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var maybe_bool: ?bool = true; if (maybe_bool) |*b| { @@ -45,6 +49,10 @@ test "rhs maybe unwrap return" { } test "maybe return" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try maybeReturnImpl(); comptime try maybeReturnImpl(); } @@ -61,6 +69,10 @@ fn foo(x: ?i32) ?bool { } test "test null runtime" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testTestNullRuntime(null); } fn testTestNullRuntime(x: ?i32) !void { @@ -69,6 +81,9 @@ fn testTestNullRuntime(x: ?i32) !void { } test "optional void" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try optionalVoidImpl(); comptime try optionalVoidImpl(); } @@ -89,6 +104,9 @@ fn bar(x: ?void) ?void { const Empty = struct {}; test "optional struct{}" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + _ = try optionalEmptyStructImpl(); _ = comptime try optionalEmptyStructImpl(); } @@ -107,17 +125,25 @@ fn baz(x: ?Empty) ?Empty { } test "null with default unwrap" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const x: i32 = null orelse 1; try expect(x == 1); } test "optional pointer to 0 bit type null value at runtime" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const EmptyStruct = struct {}; var x: ?*EmptyStruct = null; try expect(x == null); } test "if var maybe pointer" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(shouldBeAPlus1(Particle{ .a = 14, .b = 1, @@ -159,6 +185,9 @@ const here_is_a_null_literal = SillyStruct{ .context = null }; test "unwrap optional which is field of global var" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; struct_with_optional.field = null; if (struct_with_optional.field) |payload| { diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index a642da858b..2832dd01d3 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -17,6 +17,10 @@ fn testDerefPtr() !void { } test "pointer arithmetic" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var ptr: [*]const u8 = "abcd"; try expect(ptr[0] == 'a'); @@ -61,6 +65,10 @@ test "initialize const optional C pointer to null" { } test "assigning integer to C pointer" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var x: i32 = 0; var y: i32 = 1; var ptr: [*c]u8 = 0; @@ -75,6 +83,10 @@ test "assigning integer to C pointer" { } test "C pointer comparison and arithmetic" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn doTheTest() !void { var ptr1: [*c]u32 = 0; @@ -133,6 +145,10 @@ test "peer type resolution with C pointers" { } test "implicit casting between C pointer and optional non-C pointer" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var slice: []const u8 = "aoeu"; const opt_many_ptr: ?[*]const u8 = slice.ptr; var ptr_opt_many_ptr = &opt_many_ptr; @@ -172,6 +188,9 @@ test "compare equality of optional and non-optional pointer" { test "allowzero pointer and slice" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var ptr = @intToPtr([*]allowzero i32, 0); var opt_ptr: ?[*]allowzero i32 = ptr; diff --git a/test/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig b/test/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig index df116c0565..8ef037cd2c 100644 --- a/test/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig +++ b/test/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig @@ -1,9 +1,14 @@ const std = @import("std"); +const builtin = @import("builtin"); const expect = std.testing.expect; const mem = std.mem; var ok: bool = false; test "reference a variable in an if after an if in the 2nd switch prong" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try foo(true, Num.Two, false, "aoeu"); try expect(!ok); try foo(false, Num.One, false, "aoeu"); diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 5123350e20..d6ab46e757 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -248,7 +248,6 @@ test "result location zero sized array inside struct field implicit cast to slic test "runtime safety lets us slice from len..len" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var an_array = [_]u8{ 1, 2, 3 }; try expect(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), "")); diff --git a/test/behavior/src.zig b/test/behavior/src.zig index 9dd1badaae..aba23c8309 100644 --- a/test/behavior/src.zig +++ b/test/behavior/src.zig @@ -1,7 +1,10 @@ const std = @import("std"); +const builtin = @import("builtin"); const expect = std.testing.expect; test "@src" { + if (builtin.zig_backend != .stage1) return error.SkipZigTest; + try doTheTest(); } diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index bd04868f68..99dec11bf9 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -86,7 +86,8 @@ const StructFoo = struct { test "structs" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var foo: StructFoo = undefined; @memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo)); @@ -248,7 +249,8 @@ test "usingnamespace within struct scope" { test "struct field init with catch" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest() !void { @@ -310,7 +312,6 @@ test "struct point to self" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var root: Node = undefined; root.val.x = 1; @@ -350,7 +351,6 @@ test "return empty struct from fn" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO _ = testReturnEmptyStructFromFn(); } @@ -364,7 +364,6 @@ test "pass slice of empty struct to fn" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1); } @@ -409,7 +408,6 @@ test "align 1 field before self referential align 8 field as slice return type" if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const result = alloc(Expr); try expect(result.len == 0); @@ -670,7 +668,6 @@ test "default struct initialization fields" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { a: i32 = 1234, @@ -936,7 +933,6 @@ test "anonymous struct literal syntax" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { const Point = struct { diff --git a/test/behavior/this.zig b/test/behavior/this.zig index 0fcfd5910c..49b7ca69d9 100644 --- a/test/behavior/this.zig +++ b/test/behavior/this.zig @@ -1,4 +1,5 @@ const expect = @import("std").testing.expect; +const builtin = @import("builtin"); const module = @This(); @@ -20,10 +21,16 @@ fn add(x: i32, y: i32) i32 { } test "this refer to module call private fn" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(module.add(1, 2) == 3); } test "this refer to container" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var pt: Point(i32) = undefined; pt.x = 12; pt.y = 34; diff --git a/test/behavior/try.zig b/test/behavior/try.zig index 029d946588..cd8b03afab 100644 --- a/test/behavior/try.zig +++ b/test/behavior/try.zig @@ -1,6 +1,12 @@ -const expect = @import("std").testing.expect; +const std = @import("std"); +const builtin = @import("builtin"); +const expect = std.testing.expect; test "try on error union" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try tryOnErrorUnionImpl(); comptime try tryOnErrorUnionImpl(); } @@ -19,6 +25,9 @@ fn returnsTen() anyerror!i32 { } test "try without vars" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const result1 = if (failIfTrue(true)) 1 else |_| @as(i32, 2); try expect(result1 == 2); @@ -35,6 +44,9 @@ fn failIfTrue(ok: bool) anyerror!void { } test "try then not executed with assignment" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (failIfTrue(true)) { unreachable; } else |err| { diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index 8b71380de2..a3582719fd 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -186,6 +186,10 @@ fn testErrorSet() !void { } test "type info: enum info" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testEnum(); comptime try testEnum(); } @@ -249,6 +253,9 @@ fn testUnion() !void { } test "type info: struct info" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testStruct(); comptime try testStruct(); } @@ -439,6 +446,10 @@ test "type info for async frames" { } test "Declarations are returned in declaration order" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { const a = 1; const b = 2; diff --git a/test/behavior/undefined.zig b/test/behavior/undefined.zig index 280fbaf550..dcea219593 100644 --- a/test/behavior/undefined.zig +++ b/test/behavior/undefined.zig @@ -16,6 +16,8 @@ test "init static array to undefined" { // This test causes `initStaticArray()` to be codegen'd, and the // C backend does not yet support returning arrays, so it fails if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(static_array[0] == 1); try expect(static_array[4] == 2); @@ -43,6 +45,9 @@ fn setFooX(foo: *Foo) void { } test "assign undefined to struct" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + comptime { var foo: Foo = undefined; setFooX(&foo); @@ -56,6 +61,9 @@ test "assign undefined to struct" { } test "assign undefined to struct with method" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + comptime { var foo: Foo = undefined; foo.setFooXMethod(); @@ -69,6 +77,9 @@ test "assign undefined to struct with method" { } test "type name of undefined" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const x = undefined; try expect(mem.eql(u8, @typeName(@TypeOf(x)), "@Type(.Undefined)")); } diff --git a/test/behavior/underscore.zig b/test/behavior/underscore.zig index b701aac044..c15f8105aa 100644 --- a/test/behavior/underscore.zig +++ b/test/behavior/underscore.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const expect = std.testing.expect; test "ignore lval with underscore" { @@ -6,6 +7,10 @@ test "ignore lval with underscore" { } test "ignore lval with underscore (while loop)" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + while (optionalReturnError()) |_| { while (optionalReturnError()) |_| { break; diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 2e29d26941..0f8fcf5293 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -10,6 +10,10 @@ const Foo = union { }; test "basic unions" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var foo = Foo{ .int = 1 }; try expect(foo.int == 1); foo = Foo{ .float = 12.34 }; @@ -17,6 +21,10 @@ test "basic unions" { } test "init union with runtime value" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var foo: Foo = undefined; setFloat(&foo, 12.34); @@ -35,6 +43,9 @@ fn setInt(foo: *Foo, x: i32) void { } test "comptime union field access" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + comptime { var foo = Foo{ .int = 0 }; try expect(foo.int == 0); @@ -50,6 +61,10 @@ const FooExtern = extern union { }; test "basic extern unions" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var foo = FooExtern{ .int = 1 }; try expect(foo.int == 1); foo.float = 12.34; @@ -61,10 +76,16 @@ const ExternPtrOrInt = extern union { int: u64, }; test "extern union size" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + comptime try expect(@sizeOf(ExternPtrOrInt) == 8); } test "0-sized extern union definition" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const U = extern union { a: void, const f = 1; @@ -94,6 +115,9 @@ const err = @as(anyerror!Agg, Agg{ const array = [_]Value{ v1, v2, v1, v2 }; test "unions embedded in aggregate types" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + switch (array[1]) { Value.Array => |arr| try expect(arr[4] == 3), else => unreachable, @@ -105,6 +129,9 @@ test "unions embedded in aggregate types" { } test "access a member of tagged union with conflicting enum tag name" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Bar = union(enum) { A: A, B: B, @@ -117,6 +144,10 @@ test "access a member of tagged union with conflicting enum tag name" { } test "constant tagged union with payload" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var empty = TaggedUnionWithPayload{ .Empty = {} }; var full = TaggedUnionWithPayload{ .Full = 13 }; shouldBeEmpty(empty); @@ -143,6 +174,9 @@ const TaggedUnionWithPayload = union(enum) { }; test "union alignment" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + comptime { try expect(@alignOf(AlignTestTaggedUnion) >= @alignOf([9]u8)); try expect(@alignOf(AlignTestTaggedUnion) >= @alignOf(u64)); @@ -162,11 +196,18 @@ const Payload = union(Letter) { }; test "union with specified enum tag" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try doTest(); comptime try doTest(); } test "packed union generates correctly aligned LLVM type" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; const U = packed union { @@ -204,6 +245,10 @@ fn testComparison() !void { } test "comparison between union and enum literal" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testComparison(); comptime try testComparison(); } @@ -215,6 +260,10 @@ const TheUnion = union(TheTag) { C: i32, }; test "cast union to tag type of union" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testCastUnionToTag(); comptime try testCastUnionToTag(); } @@ -225,12 +274,19 @@ fn testCastUnionToTag() !void { } test "union field access gives the enum values" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(TheUnion.A == TheTag.A); try expect(TheUnion.B == TheTag.B); try expect(TheUnion.C == TheTag.C); } test "cast tag type of union to union" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var x: Value2 = Letter2.B; try expect(@as(Letter2, x) == Letter2.B); } @@ -242,6 +298,10 @@ const Value2 = union(Letter2) { }; test "implicit cast union to its tag type" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var x: Value2 = Letter2.B; try expect(x == Letter2.B); try giveMeLetterB(x); @@ -258,6 +318,10 @@ pub const PackThis = union(enum) { }; test "constant packed union" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try testConstPackedUnion(&[_]PackThis{PackThis{ .StringLiteral = 1 }}); } @@ -272,6 +336,10 @@ const MultipleChoice = union(enum(u32)) { D = 1000, }; test "simple union(enum(u32))" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var x = MultipleChoice.C; try expect(x == MultipleChoice.C); try expect(@enumToInt(@as(Tag(MultipleChoice), x)) == 60); @@ -282,6 +350,9 @@ const PackedPtrOrInt = packed union { int: u64, }; test "packed union size" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + comptime try expect(@sizeOf(PackedPtrOrInt) == 8); } @@ -289,10 +360,17 @@ const ZeroBits = union { OnlyField: void, }; test "union with only 1 field which is void should be zero bits" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + comptime try expect(@sizeOf(ZeroBits) == 0); } test "tagged union initialization with runtime void" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(testTaggedUnionInit({})); } @@ -309,6 +387,10 @@ fn testTaggedUnionInit(x: anytype) bool { pub const UnionEnumNoPayloads = union(enum) { A, B }; test "tagged union with no payloads" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const a = UnionEnumNoPayloads{ .B = {} }; switch (a) { Tag(UnionEnumNoPayloads).A => @panic("wrong"), @@ -317,6 +399,10 @@ test "tagged union with no payloads" { } test "union with only 1 field casted to its enum type" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Literal = union(enum) { Number: f64, Bool: bool, @@ -334,6 +420,9 @@ test "union with only 1 field casted to its enum type" { } test "union with one member defaults to u0 tag type" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const U0 = union(enum) { X: u32, }; @@ -348,6 +437,10 @@ const Foo1 = union(enum) { var glbl: Foo1 = undefined; test "global union with single field is correctly initialized" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -365,6 +458,10 @@ pub const FooUnion = union(enum) { var glbl_array: [2]FooUnion = undefined; test "initialize global array of union" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; @@ -375,6 +472,10 @@ test "initialize global array of union" { } test "update the tag value for zero-sized unions" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = union(enum) { U0: void, U1: void, @@ -386,6 +487,10 @@ test "update the tag value for zero-sized unions" { } test "union initializer generates padding only if needed" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const U = union(enum) { A: u24, }; @@ -395,6 +500,10 @@ test "union initializer generates padding only if needed" { } test "runtime tag name with single field" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const U = union(enum) { A: i32, }; @@ -404,6 +513,10 @@ test "runtime tag name with single field" { } test "method call on an empty union" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { const MyUnion = union(MyUnionTag) { pub const MyUnionTag = enum { X1, X2 }; @@ -441,6 +554,10 @@ const FooNoVoid = union(enum) { const Baz = enum { A, B, C, D }; test "tagged union type" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const foo1 = TaggedFoo{ .One = 13 }; const foo2 = TaggedFoo{ .Two = Point{ @@ -460,6 +577,10 @@ test "tagged union type" { } test "tagged union as return value" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + switch (returnAnInt(13)) { TaggedFoo.One => |value| try expect(value == 13), else => unreachable, @@ -471,6 +592,10 @@ fn returnAnInt(x: i32) TaggedFoo { } test "tagged union with all void fields but a meaningful tag" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { const B = union(enum) { c: C, @@ -496,6 +621,9 @@ test "tagged union with all void fields but a meaningful tag" { test "union(enum(u32)) with specified and unspecified tag values" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; comptime try expect(Tag(Tag(MultipleChoice2)) == u32); try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 }); @@ -558,6 +686,10 @@ const PartialInstWithPayload = union(enum) { }; test "union with only 1 field casted to its enum type which has enum value specified" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const Literal = union(enum) { Number: f64, Bool: bool, @@ -638,6 +770,10 @@ fn Setter(attr: Attribute) type { } test "return union init with void payload" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn entry() !void { try expect(func().state == State.one); @@ -948,6 +1084,9 @@ test "union enum type gets a separate scope" { test "global variable struct contains union initialized to non-most-aligned field" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const T = struct { const U = union(enum) { diff --git a/test/behavior/usingnamespace.zig b/test/behavior/usingnamespace.zig index ad47762c16..611b9888fa 100644 --- a/test/behavior/usingnamespace.zig +++ b/test/behavior/usingnamespace.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const expect = std.testing.expect; const A = struct { @@ -10,6 +11,9 @@ const C = struct { }; test "basic usingnamespace" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try std.testing.expect(C.B == bool); } @@ -20,6 +24,9 @@ fn Foo(comptime T: type) type { } test "usingnamespace inside a generic struct" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const std2 = Foo(std); const testing2 = Foo(std.testing); try std2.testing.expect(true); @@ -31,11 +38,17 @@ usingnamespace struct { }; test "usingnamespace does not redeclare an imported variable" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + comptime try std.testing.expect(@This().foo == 42); } usingnamespace @import("usingnamespace/foo.zig"); test "usingnamespace omits mixing in private functions" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(@This().privateFunction()); try expect(!@This().printText()); } @@ -44,10 +57,16 @@ fn privateFunction() bool { } test { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + _ = @import("usingnamespace/import_segregation.zig"); } usingnamespace @import("usingnamespace/a.zig"); test "two files usingnamespace import each other" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(@This().ok()); } diff --git a/test/behavior/void.zig b/test/behavior/void.zig index 17778d42de..800dbb1b00 100644 --- a/test/behavior/void.zig +++ b/test/behavior/void.zig @@ -1,4 +1,5 @@ const expect = @import("std").testing.expect; +const builtin = @import("builtin"); const Foo = struct { a: void, @@ -18,6 +19,9 @@ test "compare void with void compile time known" { } test "iterate over a void slice" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var j: usize = 0; for (times(10)) |_, i| { try expect(i == j); @@ -30,11 +34,18 @@ fn times(n: usize) []const void { } test "void optional" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var x: ?void = {}; try expect(x != null); } test "void array as a local variable initializer" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var x = [_]void{{}} ** 1004; _ = x[0]; } diff --git a/test/behavior/while.zig b/test/behavior/while.zig index 15dd9ee54c..36926650da 100644 --- a/test/behavior/while.zig +++ b/test/behavior/while.zig @@ -1,7 +1,11 @@ const std = @import("std"); +const builtin = @import("builtin"); const expect = std.testing.expect; test "while loop" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + var i: i32 = 0; while (i < 4) { i += 1; @@ -19,6 +23,9 @@ fn whileLoop2() i32 { } test "static eval while" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + try expect(static_eval_while_number == 1); } const static_eval_while_number = staticWhileLoop1(); @@ -98,6 +105,10 @@ fn testBreakOuter() void { } test "while copies its payload" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn doTheTest() !void { var tmp: ?i32 = 10; @@ -131,6 +142,10 @@ fn runContinueAndBreakTest() !void { } test "while with optional as condition" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + numbers_left = 10; var sum: i32 = 0; while (getNumberOrNull()) |value| { @@ -140,6 +155,10 @@ test "while with optional as condition" { } test "while with optional as condition with else" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + numbers_left = 10; var sum: i32 = 0; var got_else: i32 = 0; @@ -154,6 +173,10 @@ test "while with optional as condition with else" { } test "while with error union condition" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + numbers_left = 10; var sum: i32 = 0; var got_else: i32 = 0; @@ -182,6 +205,10 @@ test "while on bool with else result follow break prong" { } test "while on optional with else result follow else prong" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const result = while (returnNull()) |value| { break value; } else @as(i32, 2); @@ -189,6 +216,10 @@ test "while on optional with else result follow else prong" { } test "while on optional with else result follow break prong" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const result = while (returnOptional(10)) |value| { break value; } else @as(i32, 2); @@ -215,6 +246,10 @@ fn returnTrue() bool { } test "return with implicit cast from while loop" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + returnWithImplicitCastFromWhileLoopTest() catch unreachable; } fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { @@ -224,6 +259,10 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { } test "while on error union with else result follow else prong" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const result = while (returnError()) |value| { break value; } else |_| @as(i32, 2); @@ -231,6 +270,10 @@ test "while on error union with else result follow else prong" { } test "while on error union with else result follow break prong" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const result = while (returnSuccess(10)) |value| { break value; } else |_| @as(i32, 2); @@ -253,6 +296,10 @@ test "while bool 2 break statements and an else" { } test "while optional 2 break statements and an else" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + const S = struct { fn entry(opt_t: ?bool, f: bool) !void { var ok = false; -- cgit v1.2.3 From 6249a24e81b9b3df3d5ca99b57f22470b9ac486c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 23 Feb 2022 23:27:49 -0700 Subject: stage2: integer-backed packed structs This implements #10113 for the self-hosted compiler only. It removes the ability to override alignment of packed struct fields, and removes the ability to put pointers and arrays inside packed structs. After this commit, nearly all the behavior tests pass for the stage2 llvm backend that involve packed structs. I didn't implement the compile errors or compile error tests yet. I'm waiting until we have stage2 building itself and then I want to rework the compile error test harness with inspiration from Vexu's arocc test harness. At that point it should be a much nicer dev experience to work on compile errors. --- lib/std/builtin.zig | 1 + .../os/uefi/protocols/edid_override_protocol.zig | 2 +- src/AstGen.zig | 3 + src/Module.zig | 34 +- src/Sema.zig | 197 +++++----- src/codegen/llvm.zig | 402 ++++++--------------- src/type.zig | 193 ++-------- src/value.zig | 148 +++++++- test/behavior/array.zig | 10 +- test/behavior/bitcast.zig | 5 - test/behavior/sizeof_and_typeof.zig | 4 +- test/behavior/struct.zig | 144 ++++---- test/behavior/type_info.zig | 13 +- 13 files changed, 513 insertions(+), 643 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index b4d751ae30..4d0201c0db 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -356,6 +356,7 @@ pub const TypeInfo = union(enum) { alignment: comptime_int, is_generic: bool, is_var_args: bool, + /// TODO change the language spec to make this not optional. return_type: ?type, args: []const Param, diff --git a/lib/std/os/uefi/protocols/edid_override_protocol.zig b/lib/std/os/uefi/protocols/edid_override_protocol.zig index 3eb39330f4..de26e10a9e 100644 --- a/lib/std/os/uefi/protocols/edid_override_protocol.zig +++ b/lib/std/os/uefi/protocols/edid_override_protocol.zig @@ -23,7 +23,7 @@ pub const EdidOverrideProtocol = extern struct { }; pub const EdidOverrideProtocolAttributes = packed struct { - dont_override: bool align(4), + dont_override: bool, enable_hot_plug: bool, _pad: u30 = 0, }; diff --git a/src/AstGen.zig b/src/AstGen.zig index 1b2f598ace..8e2362ade1 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -4002,6 +4002,9 @@ fn structDeclInner( wip_members.nextField(bits_per_field, .{ have_align, have_value, is_comptime, unused }); if (have_align) { + if (layout == .Packed) { + try astgen.appendErrorNode(member.ast.align_expr, "unable to override alignment of packed struct fields", .{}); + } const align_inst = try expr(&block_scope, &namespace.base, align_rl, member.ast.align_expr); wip_members.appendToField(@enumToInt(align_inst)); } diff --git a/src/Module.zig b/src/Module.zig index be2a2f81d0..e596ab0aba 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -886,15 +886,6 @@ pub const Struct = struct { offset: u32, is_comptime: bool, - /// Returns the field alignment, assuming the struct is packed. - pub fn packedAlignment(field: Field) u32 { - if (field.abi_align.tag() == .abi_align_default) { - return 0; - } else { - return @intCast(u32, field.abi_align.toUnsignedInt()); - } - } - /// Returns the field alignment, assuming the struct is not packed. pub fn normalAlignment(field: Field, target: Target) u32 { if (field.abi_align.tag() == .abi_align_default) { @@ -985,6 +976,31 @@ pub const Struct = struct { => true, }; } + + pub fn packedFieldBitOffset(s: Struct, target: Target, index: usize) u16 { + assert(s.layout == .Packed); + assert(s.haveFieldTypes()); + var bit_sum: u64 = 0; + for (s.fields.values()) |field, i| { + if (i == index) { + return @intCast(u16, bit_sum); + } + bit_sum += field.ty.bitSize(target); + } + return @intCast(u16, bit_sum); + } + + pub fn packedIntegerBits(s: Struct, target: Target) u16 { + return s.packedFieldBitOffset(target, s.fields.count()); + } + + pub fn packedIntegerType(s: Struct, target: Target, buf: *Type.Payload.Bits) Type { + buf.* = .{ + .base = .{ .tag = .int_unsigned }, + .data = s.packedIntegerBits(target), + }; + return Type.initPayload(&buf.base); + } }; /// Represents the data that an enum declaration provides, when the fields diff --git a/src/Sema.zig b/src/Sema.zig index 24a376a057..bb3a516679 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -9701,7 +9701,8 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; - const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); + const unresolved_operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); + const operand_ty = try sema.resolveTypeFields(block, operand_src, unresolved_operand_ty); const target = sema.mod.getTarget(); const bit_size = operand_ty.bitSize(target); return sema.addIntUnsigned(Type.initTag(.comptime_int), bit_size); @@ -9891,6 +9892,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai .Fn => { // TODO: look into memoizing this result. const info = ty.fnInfo(); + var params_anon_decl = try block.startAnonDecl(src); defer params_anon_decl.deinit(); @@ -9948,19 +9950,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai break :v try Value.Tag.decl_ref.create(sema.arena, new_decl); }; - const field_values = try sema.arena.alloc(Value, 6); - // calling_convention: CallingConvention, - field_values[0] = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.cc)); - // alignment: comptime_int, - field_values[1] = try Value.Tag.int_u64.create(sema.arena, ty.abiAlignment(target)); - // is_generic: bool, - field_values[2] = Value.makeBool(info.is_generic); - // is_var_args: bool, - field_values[3] = Value.makeBool(info.is_var_args); - // return_type: ?type, - field_values[4] = try Value.Tag.ty.create(sema.arena, info.return_type); - // args: []const Fn.Param, - field_values[5] = args_val; + const field_values = try sema.arena.create([6]Value); + field_values.* = .{ + // calling_convention: CallingConvention, + try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.cc)), + // alignment: comptime_int, + try Value.Tag.int_u64.create(sema.arena, ty.abiAlignment(target)), + // is_generic: bool, + Value.makeBool(info.is_generic), + // is_var_args: bool, + Value.makeBool(info.is_var_args), + // return_type: ?type, + try Value.Tag.opt_payload.create( + sema.arena, + try Value.Tag.ty.create(sema.arena, info.return_type), + ), + // args: []const Fn.Param, + args_val, + }; return sema.addConstant( type_info_ty, @@ -10007,25 +10014,27 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const alignment = if (info.@"align" != 0) info.@"align" else - info.pointee_type.abiAlignment(target); - - const field_values = try sema.arena.alloc(Value, 8); - // size: Size, - field_values[0] = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.size)); - // is_const: bool, - field_values[1] = Value.makeBool(!info.mutable); - // is_volatile: bool, - field_values[2] = Value.makeBool(info.@"volatile"); - // alignment: comptime_int, - field_values[3] = try Value.Tag.int_u64.create(sema.arena, alignment); - // address_space: AddressSpace - field_values[4] = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.@"addrspace")); - // child: type, - field_values[5] = try Value.Tag.ty.create(sema.arena, info.pointee_type); - // is_allowzero: bool, - field_values[6] = Value.makeBool(info.@"allowzero"); - // sentinel: ?*const anyopaque, - field_values[7] = try sema.optRefValue(block, src, info.pointee_type, info.sentinel); + try sema.typeAbiAlignment(block, src, info.pointee_type); + + const field_values = try sema.arena.create([8]Value); + field_values.* = .{ + // size: Size, + try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.size)), + // is_const: bool, + Value.makeBool(!info.mutable), + // is_volatile: bool, + Value.makeBool(info.@"volatile"), + // alignment: comptime_int, + try Value.Tag.int_u64.create(sema.arena, alignment), + // address_space: AddressSpace + try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.@"addrspace")), + // child: type, + try Value.Tag.ty.create(sema.arena, info.pointee_type), + // is_allowzero: bool, + Value.makeBool(info.@"allowzero"), + // sentinel: ?*const anyopaque, + try sema.optRefValue(block, src, info.pointee_type, info.sentinel), + }; return sema.addConstant( type_info_ty, @@ -10377,7 +10386,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const default_val_ptr = try sema.optRefValue(block, src, field.ty, opt_default_val); const alignment = switch (layout) { .Auto, .Extern => field.normalAlignment(target), - .Packed => field.packedAlignment(), + .Packed => 0, }; struct_field_fields.* = .{ @@ -12120,6 +12129,7 @@ fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const offset = try bitOffsetOf(sema, block, inst); + // TODO reminder to make this a compile error for packed structs return sema.addIntUnsigned(Type.comptime_int, offset / 8); } @@ -12143,7 +12153,8 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 ); } - const index = ty.structFields().getIndex(field_name) orelse { + const fields = ty.structFields(); + const index = fields.getIndex(field_name) orelse { return sema.fail( block, rhs_src, @@ -12153,24 +12164,25 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 }; const target = sema.mod.getTarget(); - const layout = ty.containerLayout(); - if (layout == .Packed) { - var it = ty.iteratePackedStructOffsets(target); - while (it.next()) |field_offset| { - if (field_offset.field == index) { - return (field_offset.offset * 8) + field_offset.running_bits; - } - } - } else { - var it = ty.iterateStructOffsets(target); - while (it.next()) |field_offset| { - if (field_offset.field == index) { - return field_offset.offset * 8; - } - } + switch (ty.containerLayout()) { + .Packed => { + var bit_sum: u64 = 0; + for (fields.values()) |field, i| { + if (i == index) { + return bit_sum; + } + bit_sum += field.ty.bitSize(target); + } else unreachable; + }, + else => { + var it = ty.iterateStructOffsets(target); + while (it.next()) |field_offset| { + if (field_offset.field == index) { + return field_offset.offset * 8; + } + } else unreachable; + }, } - - unreachable; } /// Returns `true` if the type was a comptime_int. @@ -14199,61 +14211,44 @@ fn structFieldPtrByIndex( field_src: LazySrcLoc, ) CompileError!Air.Inst.Ref { const field = struct_obj.fields.values()[field_index]; - const struct_ptr_ty = sema.typeOf(struct_ptr); + const struct_ptr_ty_info = struct_ptr_ty.ptrInfo().data; + var ptr_ty_data: Type.Payload.Pointer.Data = .{ .pointee_type = field.ty, - .mutable = struct_ptr_ty.ptrIsMutable(), - .@"addrspace" = struct_ptr_ty.ptrAddressSpace(), + .mutable = struct_ptr_ty_info.mutable, + .@"addrspace" = struct_ptr_ty_info.@"addrspace", }; + // TODO handle when the struct pointer is overaligned, we should return a potentially // over-aligned field pointer too. - if (struct_obj.layout == .Packed) p: { + if (struct_obj.layout == .Packed) { const target = sema.mod.getTarget(); - comptime assert(Type.packed_struct_layout_version == 1); + comptime assert(Type.packed_struct_layout_version == 2); - var offset: u64 = 0; var running_bits: u16 = 0; for (struct_obj.fields.values()) |f, i| { if (!(try sema.typeHasRuntimeBits(block, field_src, f.ty))) continue; - const field_align = f.packedAlignment(); - if (field_align == 0) { - if (i == field_index) { - ptr_ty_data.bit_offset = running_bits; - } - running_bits += @intCast(u16, f.ty.bitSize(target)); - } else { - if (running_bits != 0) { - var int_payload: Type.Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - if (i > field_index) { - ptr_ty_data.host_size = @intCast(u16, int_ty.abiSize(target)); - break :p; - } - const int_align = int_ty.abiAlignment(target); - offset = std.mem.alignForwardGeneric(u64, offset, int_align); - offset += int_ty.abiSize(target); - running_bits = 0; - } - offset = std.mem.alignForwardGeneric(u64, offset, field_align); - if (i == field_index) { - break :p; - } - offset += f.ty.abiSize(target); + if (i == field_index) { + ptr_ty_data.bit_offset = running_bits; } + running_bits += @intCast(u16, f.ty.bitSize(target)); + } + ptr_ty_data.host_size = (running_bits + 7) / 8; + + // If this is a packed struct embedded in another one, we need to offset + // the bits against each other. + if (struct_ptr_ty_info.host_size != 0) { + ptr_ty_data.host_size = struct_ptr_ty_info.host_size; + ptr_ty_data.bit_offset += struct_ptr_ty_info.bit_offset; + } + } else { + if (field.abi_align.tag() != .abi_align_default) { + ptr_ty_data.@"align" = @intCast(u32, field.abi_align.toUnsignedInt()); } - assert(running_bits != 0); - var int_payload: Type.Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - ptr_ty_data.host_size = @intCast(u16, int_ty.abiSize(target)); } + const ptr_field_ty = try Type.ptr(sema.arena, ptr_ty_data); if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| { @@ -15849,13 +15844,18 @@ fn beginComptimePtrLoad( fn bitCast( sema: *Sema, block: *Block, - dest_ty: Type, + dest_ty_unresolved: Type, inst: Air.Inst.Ref, inst_src: LazySrcLoc, ) CompileError!Air.Inst.Ref { + const dest_ty = try sema.resolveTypeFields(block, inst_src, dest_ty_unresolved); + try sema.resolveTypeLayout(block, inst_src, dest_ty); + + const old_ty = try sema.resolveTypeFields(block, inst_src, sema.typeOf(inst)); + try sema.resolveTypeLayout(block, inst_src, old_ty); + // TODO validate the type size and other compile errors if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { - const old_ty = sema.typeOf(inst); const result_val = try sema.bitCastVal(block, inst_src, val, old_ty, dest_ty); return sema.addConstant(dest_ty, result_val); } @@ -17506,6 +17506,9 @@ fn semaStructFields( // But only resolve the source location if we need to emit a compile error. try sema.resolveType(&block_scope, src, field_type_ref); + // TODO emit compile errors for invalid field types + // such as arrays and pointers inside packed structs. + const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name); assert(!gop.found_existing); gop.value_ptr.* = .{ @@ -18690,6 +18693,12 @@ pub fn typeHasRuntimeBits(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) return true; } +fn typeAbiAlignment(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u32 { + try sema.resolveTypeLayout(block, src, ty); + const target = sema.mod.getTarget(); + return ty.abiAlignment(target); +} + /// Synchronize logic with `Type.isFnOrHasRuntimeBits`. pub fn fnHasRuntimeBits(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { const fn_info = ty.fnInfo(); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 8beb4dd206..1679ee6d97 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -865,8 +865,12 @@ pub const DeclGen = struct { }; return dg.context.structType(&fields, fields.len, .False); } - const llvm_addrspace = dg.llvmAddressSpace(t.ptrAddressSpace()); - const elem_ty = t.childType(); + const ptr_info = t.ptrInfo().data; + const llvm_addrspace = dg.llvmAddressSpace(ptr_info.@"addrspace"); + if (ptr_info.host_size != 0) { + return dg.context.intType(ptr_info.host_size * 8).pointerType(llvm_addrspace); + } + const elem_ty = ptr_info.pointee_type; const lower_elem_ty = switch (elem_ty.zigTypeTag()) { .Opaque, .Fn => true, .Array => elem_ty.childType().hasRuntimeBits(), @@ -977,6 +981,14 @@ pub const DeclGen = struct { const struct_obj = t.castTag(.@"struct").?.data; + if (struct_obj.layout == .Packed) { + var buf: Type.Payload.Bits = undefined; + const int_ty = struct_obj.packedIntegerType(target, &buf); + const int_llvm_ty = try dg.llvmType(int_ty); + gop.value_ptr.* = int_llvm_ty; + return int_llvm_ty; + } + const name = try struct_obj.getFullyQualifiedName(gpa); defer gpa.free(name); @@ -988,83 +1000,9 @@ pub const DeclGen = struct { var llvm_field_types = try std.ArrayListUnmanaged(*const llvm.Type).initCapacity(gpa, struct_obj.fields.count()); defer llvm_field_types.deinit(gpa); - if (struct_obj.layout == .Packed) { - try llvm_field_types.ensureUnusedCapacity(gpa, struct_obj.fields.count() * 2); - comptime assert(Type.packed_struct_layout_version == 1); - var offset: u64 = 0; - var big_align: u32 = 0; - var running_bits: u16 = 0; - for (struct_obj.fields.values()) |field| { - if (!field.ty.hasRuntimeBits()) continue; - - const field_align = field.packedAlignment(); - if (field_align == 0) { - running_bits += @intCast(u16, field.ty.bitSize(target)); - } else { - if (running_bits != 0) { - var int_payload: Type.Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - const int_align = int_ty.abiAlignment(target); - big_align = @maximum(big_align, int_align); - const llvm_int_ty = try dg.llvmType(int_ty); - const prev_offset = offset; - offset = std.mem.alignForwardGeneric(u64, offset, int_align); - const padding_bytes = @intCast(c_uint, offset - prev_offset); - if (padding_bytes != 0) { - const padding = dg.context.intType(8).arrayType(padding_bytes); - llvm_field_types.appendAssumeCapacity(padding); - } - llvm_field_types.appendAssumeCapacity(llvm_int_ty); - offset += int_ty.abiSize(target); - running_bits = 0; - } - big_align = @maximum(big_align, field_align); - const prev_offset = offset; - offset = std.mem.alignForwardGeneric(u64, offset, field_align); - const padding_bytes = @intCast(c_uint, offset - prev_offset); - if (padding_bytes != 0) { - const padding = dg.context.intType(8).arrayType(padding_bytes); - llvm_field_types.appendAssumeCapacity(padding); - } - llvm_field_types.appendAssumeCapacity(try dg.llvmType(field.ty)); - offset += field.ty.abiSize(target); - } - } - - if (running_bits != 0) { - var int_payload: Type.Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - const int_align = int_ty.abiAlignment(target); - big_align = @maximum(big_align, int_align); - const prev_offset = offset; - offset = std.mem.alignForwardGeneric(u64, offset, int_align); - const padding_bytes = @intCast(c_uint, offset - prev_offset); - if (padding_bytes != 0) { - const padding = dg.context.intType(8).arrayType(padding_bytes); - llvm_field_types.appendAssumeCapacity(padding); - } - const llvm_int_ty = try dg.llvmType(int_ty); - llvm_field_types.appendAssumeCapacity(llvm_int_ty); - } - - const prev_offset = offset; - offset = std.mem.alignForwardGeneric(u64, offset, big_align); - const padding_bytes = @intCast(c_uint, offset - prev_offset); - if (padding_bytes != 0) { - const padding = dg.context.intType(8).arrayType(padding_bytes); - llvm_field_types.appendAssumeCapacity(padding); - } - } else { - for (struct_obj.fields.values()) |field| { - if (!field.ty.hasRuntimeBits()) continue; - llvm_field_types.appendAssumeCapacity(try dg.llvmType(field.ty)); - } + for (struct_obj.fields.values()) |field| { + if (!field.ty.hasRuntimeBits()) continue; + llvm_field_types.appendAssumeCapacity(try dg.llvmType(field.ty)); } llvm_struct_ty.structSetBody( @@ -1521,116 +1459,54 @@ pub const DeclGen = struct { const llvm_struct_ty = try dg.llvmType(tv.ty); const field_vals = tv.val.castTag(.@"struct").?.data; const gpa = dg.gpa; - const llvm_field_count = llvm_struct_ty.countStructElementTypes(); - - var llvm_fields = try std.ArrayListUnmanaged(*const llvm.Value).initCapacity(gpa, llvm_field_count); - defer llvm_fields.deinit(gpa); - - var need_unnamed = false; const struct_obj = tv.ty.castTag(.@"struct").?.data; + if (struct_obj.layout == .Packed) { const target = dg.module.getTarget(); + var int_ty_buf: Type.Payload.Bits = undefined; + const int_ty = struct_obj.packedIntegerType(target, &int_ty_buf); + const int_llvm_ty = try dg.llvmType(int_ty); const fields = struct_obj.fields.values(); - comptime assert(Type.packed_struct_layout_version == 1); - var offset: u64 = 0; - var big_align: u32 = 0; + comptime assert(Type.packed_struct_layout_version == 2); + var running_int: *const llvm.Value = int_llvm_ty.constNull(); var running_bits: u16 = 0; - var running_int: *const llvm.Value = llvm_struct_ty.structGetTypeAtIndex(0).constNull(); for (field_vals) |field_val, i| { const field = fields[i]; if (!field.ty.hasRuntimeBits()) continue; - const field_align = field.packedAlignment(); - if (field_align == 0) { - const non_int_val = try dg.genTypedValue(.{ - .ty = field.ty, - .val = field_val, - }); - const ty_bit_size = @intCast(u16, field.ty.bitSize(target)); - const small_int_ty = dg.context.intType(ty_bit_size); - const small_int_val = non_int_val.constBitCast(small_int_ty); - const big_int_ty = running_int.typeOf(); - const shift_rhs = big_int_ty.constInt(running_bits, .False); - const extended_int_val = small_int_val.constZExt(big_int_ty); - const shifted = extended_int_val.constShl(shift_rhs); - running_int = running_int.constOr(shifted); - running_bits += ty_bit_size; - } else { - big_align = @maximum(big_align, field_align); - if (running_bits != 0) { - var int_payload: Type.Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - const int_align = int_ty.abiAlignment(target); - big_align = @maximum(big_align, int_align); - const prev_offset = offset; - offset = std.mem.alignForwardGeneric(u64, offset, int_align); - const padding_bytes = @intCast(c_uint, offset - prev_offset); - if (padding_bytes != 0) { - const padding = dg.context.intType(8).arrayType(padding_bytes); - llvm_fields.appendAssumeCapacity(padding.getUndef()); - } - llvm_fields.appendAssumeCapacity(running_int); - running_int = llvm_struct_ty.structGetTypeAtIndex(@intCast(c_uint, llvm_fields.items.len)).constNull(); - offset += int_ty.abiSize(target); - running_bits = 0; - } - const prev_offset = offset; - offset = std.mem.alignForwardGeneric(u64, offset, field_align); - const padding_bytes = @intCast(c_uint, offset - prev_offset); - if (padding_bytes != 0) { - const padding = dg.context.intType(8).arrayType(padding_bytes); - llvm_fields.appendAssumeCapacity(padding.getUndef()); - } - llvm_fields.appendAssumeCapacity(try dg.genTypedValue(.{ - .ty = field.ty, - .val = field_val, - })); - offset += field.ty.abiSize(target); - } - } - if (running_bits != 0) { - var int_payload: Type.Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - const int_align = int_ty.abiAlignment(target); - big_align = @maximum(big_align, int_align); - const prev_offset = offset; - offset = std.mem.alignForwardGeneric(u64, offset, int_align); - const padding_bytes = @intCast(c_uint, offset - prev_offset); - if (padding_bytes != 0) { - const padding = dg.context.intType(8).arrayType(padding_bytes); - llvm_fields.appendAssumeCapacity(padding.getUndef()); - } - llvm_fields.appendAssumeCapacity(running_int); - offset += int_ty.abiSize(target); + const non_int_val = try dg.genTypedValue(.{ + .ty = field.ty, + .val = field_val, + }); + const ty_bit_size = @intCast(u16, field.ty.bitSize(target)); + const small_int_ty = dg.context.intType(ty_bit_size); + const small_int_val = non_int_val.constBitCast(small_int_ty); + const shift_rhs = int_llvm_ty.constInt(running_bits, .False); + const extended_int_val = small_int_val.constZExt(int_llvm_ty); + const shifted = extended_int_val.constShl(shift_rhs); + running_int = running_int.constOr(shifted); + running_bits += ty_bit_size; } + return running_int; + } - const prev_offset = offset; - offset = std.mem.alignForwardGeneric(u64, offset, big_align); - const padding_bytes = @intCast(c_uint, offset - prev_offset); - if (padding_bytes != 0) { - const padding = dg.context.intType(8).arrayType(padding_bytes); - llvm_fields.appendAssumeCapacity(padding.getUndef()); - } - } else { - for (field_vals) |field_val, i| { - const field_ty = tv.ty.structFieldType(i); - if (!field_ty.hasRuntimeBits()) continue; + const llvm_field_count = llvm_struct_ty.countStructElementTypes(); + var llvm_fields = try std.ArrayListUnmanaged(*const llvm.Value).initCapacity(gpa, llvm_field_count); + defer llvm_fields.deinit(gpa); - const field_llvm_val = try dg.genTypedValue(.{ - .ty = field_ty, - .val = field_val, - }); + var need_unnamed = false; + for (field_vals) |field_val, i| { + const field_ty = tv.ty.structFieldType(i); + if (!field_ty.hasRuntimeBits()) continue; - need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field_llvm_val); + const field_llvm_val = try dg.genTypedValue(.{ + .ty = field_ty, + .val = field_val, + }); - llvm_fields.appendAssumeCapacity(field_llvm_val); - } + need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field_llvm_val); + + llvm_fields.appendAssumeCapacity(field_llvm_val); } if (need_unnamed) { @@ -2923,10 +2799,27 @@ pub const FuncGen = struct { if (!isByRef(struct_ty)) { assert(!isByRef(field_ty)); switch (struct_ty.zigTypeTag()) { - .Struct => { - var ptr_ty_buf: Type.Payload.Pointer = undefined; - const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ptr_ty_buf).?; - return self.builder.buildExtractValue(struct_llvm_val, llvm_field_index, ""); + .Struct => switch (struct_ty.containerLayout()) { + .Packed => { + const struct_obj = struct_ty.castTag(.@"struct").?.data; + const bit_offset = struct_obj.packedFieldBitOffset(target, field_index); + const containing_int = struct_llvm_val; + const shift_amt = containing_int.typeOf().constInt(bit_offset, .False); + const shifted_value = self.builder.buildLShr(containing_int, shift_amt, ""); + const elem_llvm_ty = try self.dg.llvmType(field_ty); + if (field_ty.zigTypeTag() == .Float) { + const elem_bits = @intCast(c_uint, field_ty.bitSize(target)); + const same_size_int = self.context.intType(elem_bits); + const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, ""); + return self.builder.buildBitCast(truncated_int, elem_llvm_ty, ""); + } + return self.builder.buildTrunc(shifted_value, elem_llvm_ty, ""); + }, + else => { + var ptr_ty_buf: Type.Payload.Pointer = undefined; + const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ptr_ty_buf).?; + return self.builder.buildExtractValue(struct_llvm_val, llvm_field_index, ""); + }, }, .Union => { return self.todo("airStructFieldVal byval union", .{}); @@ -2937,6 +2830,7 @@ pub const FuncGen = struct { switch (struct_ty.zigTypeTag()) { .Struct => { + assert(struct_ty.containerLayout() != .Packed); var ptr_ty_buf: Type.Payload.Pointer = undefined; const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ptr_ty_buf).?; const field_ptr = self.builder.buildStructGEP(struct_llvm_val, llvm_field_index, ""); @@ -4928,21 +4822,35 @@ pub const FuncGen = struct { ) !?*const llvm.Value { const struct_ty = struct_ptr_ty.childType(); switch (struct_ty.zigTypeTag()) { - .Struct => { - const target = self.dg.module.getTarget(); - var ty_buf: Type.Payload.Pointer = undefined; - if (llvmFieldIndex(struct_ty, field_index, target, &ty_buf)) |llvm_field_index| { - return self.builder.buildStructGEP(struct_ptr, llvm_field_index, ""); - } else { - // If we found no index then this means this is a zero sized field at the - // end of the struct. Treat our struct pointer as an array of two and get - // the index to the element at index `1` to get a pointer to the end of - // the struct. - const llvm_usize = try self.dg.llvmType(Type.usize); - const llvm_index = llvm_usize.constInt(1, .False); - const indices: [1]*const llvm.Value = .{llvm_index}; - return self.builder.buildInBoundsGEP(struct_ptr, &indices, indices.len, ""); - } + .Struct => switch (struct_ty.containerLayout()) { + .Packed => { + // From LLVM's perspective, a pointer to a packed struct and a pointer + // to a field of a packed struct are the same. The difference is in the + // Zig pointer type which provides information for how to mask and shift + // out the relevant bits when accessing the pointee. + // Here we perform a bitcast because we want to use the host_size + // as the llvm pointer element type. + const result_llvm_ty = try self.dg.llvmType(self.air.typeOfIndex(inst)); + // TODO this can be removed if we change host_size to be bits instead + // of bytes. + return self.builder.buildBitCast(struct_ptr, result_llvm_ty, ""); + }, + else => { + const target = self.dg.module.getTarget(); + var ty_buf: Type.Payload.Pointer = undefined; + if (llvmFieldIndex(struct_ty, field_index, target, &ty_buf)) |llvm_field_index| { + return self.builder.buildStructGEP(struct_ptr, llvm_field_index, ""); + } else { + // If we found no index then this means this is a zero sized field at the + // end of the struct. Treat our struct pointer as an array of two and get + // the index to the element at index `1` to get a pointer to the end of + // the struct. + const llvm_usize = try self.dg.llvmType(Type.usize); + const llvm_index = llvm_usize.constInt(1, .False); + const indices: [1]*const llvm.Value = .{llvm_index}; + return self.builder.buildInBoundsGEP(struct_ptr, &indices, indices.len, ""); + } + }, }, .Union => return self.unionFieldPtr(inst, struct_ptr, struct_ty, field_index), else => unreachable, @@ -5373,102 +5281,29 @@ fn llvmFieldIndex( return null; } const struct_obj = ty.castTag(.@"struct").?.data; - if (struct_obj.layout != .Packed) { - var llvm_field_index: c_uint = 0; - for (struct_obj.fields.values()) |field, i| { - if (!field.ty.hasRuntimeBits()) - continue; - if (field_index > i) { - llvm_field_index += 1; - continue; - } + assert(struct_obj.layout != .Packed); - ptr_pl_buf.* = .{ - .data = .{ - .pointee_type = field.ty, - .@"align" = field.normalAlignment(target), - .@"addrspace" = .generic, - }, - }; - return llvm_field_index; - } else { - // We did not find an llvm field that corresponds to this zig field. - return null; - } - } - - // Our job here is to return the host integer field index. - comptime assert(Type.packed_struct_layout_version == 1); - var offset: u64 = 0; - var running_bits: u16 = 0; var llvm_field_index: c_uint = 0; for (struct_obj.fields.values()) |field, i| { if (!field.ty.hasRuntimeBits()) continue; - - const field_align = field.packedAlignment(); - if (field_align == 0) { - if (i == field_index) { - ptr_pl_buf.* = .{ - .data = .{ - .pointee_type = field.ty, - .bit_offset = running_bits, - .@"addrspace" = .generic, - }, - }; - } - running_bits += @intCast(u16, field.ty.bitSize(target)); - } else { - if (running_bits != 0) { - var int_payload: Type.Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - if (i > field_index) { - ptr_pl_buf.data.host_size = @intCast(u16, int_ty.abiSize(target)); - return llvm_field_index; - } - - const int_align = int_ty.abiAlignment(target); - const prev_offset = offset; - offset = std.mem.alignForwardGeneric(u64, offset, int_align); - const padding_bytes = @intCast(c_uint, offset - prev_offset); - if (padding_bytes != 0) { - llvm_field_index += 1; - } - llvm_field_index += 1; - offset += int_ty.abiSize(target); - running_bits = 0; - } - const prev_offset = offset; - offset = std.mem.alignForwardGeneric(u64, offset, field_align); - const padding_bytes = @intCast(c_uint, offset - prev_offset); - if (padding_bytes != 0) { - llvm_field_index += 1; - } - if (i == field_index) { - ptr_pl_buf.* = .{ - .data = .{ - .pointee_type = field.ty, - .@"align" = field_align, - .@"addrspace" = .generic, - }, - }; - return llvm_field_index; - } + if (field_index > i) { llvm_field_index += 1; - offset += field.ty.abiSize(target); + continue; } + + ptr_pl_buf.* = .{ + .data = .{ + .pointee_type = field.ty, + .@"align" = field.normalAlignment(target), + .@"addrspace" = .generic, + }, + }; + return llvm_field_index; + } else { + // We did not find an llvm field that corresponds to this zig field. + return null; } - assert(running_bits != 0); - var int_payload: Type.Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - ptr_pl_buf.data.host_size = @intCast(u16, int_ty.abiSize(target)); - return llvm_field_index; } fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool { @@ -5518,6 +5353,9 @@ fn isByRef(ty: Type) bool { .Array, .Frame => return ty.hasRuntimeBits(), .Struct => { + // Packed structs are represented to LLVM as integers. + if (ty.containerLayout() == .Packed) return false; + if (!ty.hasRuntimeBits()) return false; if (ty.castTag(.tuple)) |tuple| { var count: usize = 0; diff --git a/src/type.zig b/src/type.zig index 2454dfb5b5..4eb78b0656 100644 --- a/src/type.zig +++ b/src/type.zig @@ -1952,57 +1952,22 @@ pub const Type = extern union { .@"struct" => { const fields = self.structFields(); - const is_packed = if (self.castTag(.@"struct")) |payload| p: { + if (self.castTag(.@"struct")) |payload| { const struct_obj = payload.data; assert(struct_obj.haveLayout()); - break :p struct_obj.layout == .Packed; - } else false; - - if (!is_packed) { - var big_align: u32 = 0; - for (fields.values()) |field| { - if (!field.ty.hasRuntimeBits()) continue; - - const field_align = field.normalAlignment(target); - big_align = @maximum(big_align, field_align); + if (struct_obj.layout == .Packed) { + var buf: Type.Payload.Bits = undefined; + const int_ty = struct_obj.packedIntegerType(target, &buf); + return int_ty.abiAlignment(target); } - return big_align; } - // For packed structs, we take the maximum alignment of the backing integers. - comptime assert(Type.packed_struct_layout_version == 1); var big_align: u32 = 0; - var running_bits: u16 = 0; - for (fields.values()) |field| { if (!field.ty.hasRuntimeBits()) continue; - const field_align = field.packedAlignment(); - if (field_align == 0) { - running_bits += @intCast(u16, field.ty.bitSize(target)); - } else { - if (running_bits != 0) { - var int_payload: Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - const int_align = int_ty.abiAlignment(target); - big_align = @maximum(big_align, int_align); - running_bits = 0; - } - big_align = @maximum(big_align, field_align); - } - } - - if (running_bits != 0) { - var int_payload: Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - const int_align = int_ty.abiAlignment(target); - big_align = @maximum(big_align, int_align); + const field_align = field.normalAlignment(target); + big_align = @maximum(big_align, field_align); } return big_align; }, @@ -2090,12 +2055,20 @@ pub const Type = extern union { .void, => 0, - .@"struct", .tuple => { - const field_count = self.structFieldCount(); - if (field_count == 0) { - return 0; - } - return self.structFieldOffset(field_count, target); + .@"struct", .tuple => switch (self.containerLayout()) { + .Packed => { + const struct_obj = self.castTag(.@"struct").?.data; + var buf: Type.Payload.Bits = undefined; + const int_ty = struct_obj.packedIntegerType(target, &buf); + return int_ty.abiSize(target); + }, + else => { + const field_count = self.structFieldCount(); + if (field_count == 0) { + return 0; + } + return self.structFieldOffset(field_count, target); + }, }, .enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => { @@ -2264,7 +2237,6 @@ pub const Type = extern union { .fn_ccc_void_no_args => unreachable, // represents machine code; not a pointer .function => unreachable, // represents machine code; not a pointer .anyopaque => unreachable, - .void => unreachable, .type => unreachable, .comptime_int => unreachable, .comptime_float => unreachable, @@ -2282,18 +2254,25 @@ pub const Type = extern union { .generic_poison => unreachable, .bound_fn => unreachable, + .void => 0, + .@"struct" => { const field_count = ty.structFieldCount(); if (field_count == 0) return 0; const struct_obj = ty.castTag(.@"struct").?.data; - assert(struct_obj.haveLayout()); + assert(struct_obj.haveFieldTypes()); - var total: u64 = 0; - for (struct_obj.fields.values()) |field| { - total += field.ty.bitSize(target); + switch (struct_obj.layout) { + .Auto, .Extern => { + var total: u64 = 0; + for (struct_obj.fields.values()) |field| { + total += field.ty.bitSize(target); + } + return total; + }, + .Packed => return struct_obj.packedIntegerBits(target), } - return total; }, .tuple => { @@ -4039,78 +4018,6 @@ pub const Type = extern union { } } - pub const PackedFieldOffset = struct { - field: usize, - offset: u64, - running_bits: u16, - }; - - pub const PackedStructOffsetIterator = struct { - field: usize = 0, - offset: u64 = 0, - big_align: u32 = 0, - running_bits: u16 = 0, - struct_obj: *Module.Struct, - target: Target, - - pub fn next(it: *PackedStructOffsetIterator) ?PackedFieldOffset { - comptime assert(Type.packed_struct_layout_version == 1); - if (it.struct_obj.fields.count() <= it.field) - return null; - - const field = it.struct_obj.fields.values()[it.field]; - defer it.field += 1; - if (!field.ty.hasRuntimeBits()) { - return PackedFieldOffset{ - .field = it.field, - .offset = it.offset, - .running_bits = it.running_bits, - }; - } - - const field_align = field.packedAlignment(); - if (field_align == 0) { - defer it.running_bits += @intCast(u16, field.ty.bitSize(it.target)); - return PackedFieldOffset{ - .field = it.field, - .offset = it.offset, - .running_bits = it.running_bits, - }; - } else { - it.big_align = @maximum(it.big_align, field_align); - - if (it.running_bits != 0) { - var int_payload: Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = it.running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - const int_align = int_ty.abiAlignment(it.target); - it.big_align = @maximum(it.big_align, int_align); - it.offset = std.mem.alignForwardGeneric(u64, it.offset, int_align); - it.offset += int_ty.abiSize(it.target); - it.running_bits = 0; - } - it.offset = std.mem.alignForwardGeneric(u64, it.offset, field_align); - defer it.offset += field.ty.abiSize(it.target); - return PackedFieldOffset{ - .field = it.field, - .offset = it.offset, - .running_bits = it.running_bits, - }; - } - } - }; - - /// Get an iterator that iterates over all the struct field, returning the field and - /// offset of that field. Asserts that the type is a none packed struct. - pub fn iteratePackedStructOffsets(ty: Type, target: Target) PackedStructOffsetIterator { - const struct_obj = ty.castTag(.@"struct").?.data; - assert(struct_obj.haveLayout()); - assert(struct_obj.layout == .Packed); - return .{ .struct_obj = struct_obj, .target = target }; - } - pub const FieldOffset = struct { field: usize, offset: u64, @@ -4150,42 +4057,19 @@ pub const Type = extern union { } /// Supports structs and unions. - /// For packed structs, it returns the byte offset of the containing integer. pub fn structFieldOffset(ty: Type, index: usize, target: Target) u64 { switch (ty.tag()) { .@"struct" => { const struct_obj = ty.castTag(.@"struct").?.data; assert(struct_obj.haveLayout()); - const is_packed = struct_obj.layout == .Packed; - if (!is_packed) { - var it = ty.iterateStructOffsets(target); - while (it.next()) |field_offset| { - if (index == field_offset.field) - return field_offset.offset; - } - - return std.mem.alignForwardGeneric(u64, it.offset, it.big_align); - } - - var it = ty.iteratePackedStructOffsets(target); + assert(struct_obj.layout != .Packed); + var it = ty.iterateStructOffsets(target); while (it.next()) |field_offset| { if (index == field_offset.field) return field_offset.offset; } - if (it.running_bits != 0) { - var int_payload: Payload.Bits = .{ - .base = .{ .tag = .int_unsigned }, - .data = it.running_bits, - }; - const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; - const int_align = int_ty.abiAlignment(target); - it.big_align = @maximum(it.big_align, int_align); - it.offset = std.mem.alignForwardGeneric(u64, it.offset, int_align); - it.offset += int_ty.abiSize(target); - } - it.offset = std.mem.alignForwardGeneric(u64, it.offset, it.big_align); - return it.offset; + return std.mem.alignForwardGeneric(u64, it.offset, it.big_align); }, .tuple => { @@ -4734,6 +4618,9 @@ pub const Type = extern union { /// an appropriate value for this field. @"addrspace": std.builtin.AddressSpace, bit_offset: u16 = 0, + /// If this is non-zero it means the pointer points to a sub-byte + /// range of data, which is backed by a "host integer" with this + /// number of bytes. host_size: u16 = 0, @"allowzero": bool = false, mutable: bool = true, // TODO rename this to const, not mutable @@ -4953,7 +4840,7 @@ pub const Type = extern union { /// This is only used for comptime asserts. Bump this number when you make a change /// to packed struct layout to find out all the places in the codebase you need to edit! - pub const packed_struct_layout_version = 1; + pub const packed_struct_layout_version = 2; }; pub const CType = enum { diff --git a/src/value.zig b/src/value.zig index a4e3bf68a1..538c20587b 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1078,18 +1078,72 @@ pub const Value = extern union { buf_off += elem_size; } }, - .Struct => { - const fields = ty.structFields().values(); - const field_vals = val.castTag(.@"struct").?.data; - for (fields) |field, i| { - const off = @intCast(usize, ty.structFieldOffset(i, target)); - writeToMemory(field_vals[i], field.ty, target, buffer[off..]); - } + .Struct => switch (ty.containerLayout()) { + .Auto => unreachable, // Sema is supposed to have emitted a compile error already + .Extern => { + const fields = ty.structFields().values(); + const field_vals = val.castTag(.@"struct").?.data; + for (fields) |field, i| { + const off = @intCast(usize, ty.structFieldOffset(i, target)); + writeToMemory(field_vals[i], field.ty, target, buffer[off..]); + } + }, + .Packed => { + // TODO allocate enough heap space instead of using this buffer + // on the stack. + var buf: [16]std.math.big.Limb = undefined; + const host_int = packedStructToInt(val, ty, target, &buf); + const abi_size = @intCast(usize, ty.abiSize(target)); + const bit_size = @intCast(usize, ty.bitSize(target)); + host_int.writeTwosComplement(buffer, bit_size, abi_size, target.cpu.arch.endian()); + }, }, else => @panic("TODO implement writeToMemory for more types"), } } + fn packedStructToInt(val: Value, ty: Type, target: Target, buf: []std.math.big.Limb) BigIntConst { + var bigint = BigIntMutable.init(buf, 0); + const fields = ty.structFields().values(); + const field_vals = val.castTag(.@"struct").?.data; + var bits: u16 = 0; + // TODO allocate enough heap space instead of using this buffer + // on the stack. + var field_buf: [16]std.math.big.Limb = undefined; + var field_space: BigIntSpace = undefined; + var field_buf2: [16]std.math.big.Limb = undefined; + for (fields) |field, i| { + const field_val = field_vals[i]; + const field_bigint_const = switch (field.ty.zigTypeTag()) { + .Float => switch (field.ty.floatBits(target)) { + 16 => bitcastFloatToBigInt(f16, val.toFloat(f16), &field_buf), + 32 => bitcastFloatToBigInt(f32, val.toFloat(f32), &field_buf), + 64 => bitcastFloatToBigInt(f64, val.toFloat(f64), &field_buf), + 80 => bitcastFloatToBigInt(f80, val.toFloat(f80), &field_buf), + 128 => bitcastFloatToBigInt(f128, val.toFloat(f128), &field_buf), + else => unreachable, + }, + .Int, .Bool => field_val.toBigInt(&field_space), + .Struct => packedStructToInt(field_val, field.ty, target, &field_buf), + else => unreachable, + }; + var field_bigint = BigIntMutable.init(&field_buf2, 0); + field_bigint.shiftLeft(field_bigint_const, bits); + bits += @intCast(u16, field.ty.bitSize(target)); + bigint.bitOr(bigint.toConst(), field_bigint.toConst()); + } + return bigint.toConst(); + } + + fn bitcastFloatToBigInt(comptime F: type, f: F, buf: []std.math.big.Limb) BigIntConst { + const Int = @Type(.{ .Int = .{ + .signedness = .unsigned, + .bits = @typeInfo(F).Float.bits, + } }); + const int = @bitCast(Int, f); + return BigIntMutable.init(buf, int).toConst(); + } + pub fn readFromMemory( ty: Type, target: Target, @@ -1127,10 +1181,90 @@ pub const Value = extern union { } return Tag.array.create(arena, elems); }, + .Struct => switch (ty.containerLayout()) { + .Auto => unreachable, // Sema is supposed to have emitted a compile error already + .Extern => { + const fields = ty.structFields().values(); + const field_vals = try arena.alloc(Value, fields.len); + for (fields) |field, i| { + const off = @intCast(usize, ty.structFieldOffset(i, target)); + field_vals[i] = try readFromMemory(field.ty, target, buffer[off..], arena); + } + return Tag.@"struct".create(arena, field_vals); + }, + .Packed => { + const endian = target.cpu.arch.endian(); + const Limb = std.math.big.Limb; + const abi_size = @intCast(usize, ty.abiSize(target)); + const bit_size = @intCast(usize, ty.bitSize(target)); + const limb_count = (buffer.len + @sizeOf(Limb) - 1) / @sizeOf(Limb); + const limbs_buffer = try arena.alloc(Limb, limb_count); + var bigint = BigIntMutable.init(limbs_buffer, 0); + bigint.readTwosComplement(buffer, bit_size, abi_size, endian, .unsigned); + return intToPackedStruct(ty, target, bigint.toConst(), arena); + }, + }, else => @panic("TODO implement readFromMemory for more types"), } } + fn intToPackedStruct( + ty: Type, + target: Target, + bigint: BigIntConst, + arena: Allocator, + ) Allocator.Error!Value { + const limbs_buffer = try arena.alloc(std.math.big.Limb, bigint.limbs.len); + var bigint_mut = bigint.toMutable(limbs_buffer); + const fields = ty.structFields().values(); + const field_vals = try arena.alloc(Value, fields.len); + var bits: u16 = 0; + for (fields) |field, i| { + const field_bits = @intCast(u16, field.ty.bitSize(target)); + bigint_mut.shiftRight(bigint, bits); + bigint_mut.truncate(bigint_mut.toConst(), .unsigned, field_bits); + bits += field_bits; + const field_bigint = bigint_mut.toConst(); + + field_vals[i] = switch (field.ty.zigTypeTag()) { + .Float => switch (field.ty.floatBits(target)) { + 16 => try bitCastBigIntToFloat(f16, .float_16, field_bigint, arena), + 32 => try bitCastBigIntToFloat(f32, .float_32, field_bigint, arena), + 64 => try bitCastBigIntToFloat(f64, .float_64, field_bigint, arena), + 80 => try bitCastBigIntToFloat(f80, .float_80, field_bigint, arena), + 128 => try bitCastBigIntToFloat(f128, .float_128, field_bigint, arena), + else => unreachable, + }, + .Bool => makeBool(!field_bigint.eqZero()), + .Int => try Tag.int_big_positive.create( + arena, + try arena.dupe(std.math.big.Limb, field_bigint.limbs), + ), + .Struct => try intToPackedStruct(field.ty, target, field_bigint, arena), + else => unreachable, + }; + } + return Tag.@"struct".create(arena, field_vals); + } + + fn bitCastBigIntToFloat( + comptime F: type, + comptime float_tag: Tag, + bigint: BigIntConst, + arena: Allocator, + ) !Value { + const Int = @Type(.{ .Int = .{ + .signedness = .unsigned, + .bits = @typeInfo(F).Float.bits, + } }); + const int = bigint.to(Int) catch |err| switch (err) { + error.NegativeIntoUnsigned => unreachable, + error.TargetTooSmall => unreachable, + }; + const f = @bitCast(F, int); + return float_tag.create(arena, f); + } + fn floatWriteToMemory(comptime F: type, f: F, target: Target, buffer: []u8) void { if (F == f80) { switch (target.cpu.arch) { diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 0bbdad44c4..2d4d1368f5 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -473,8 +473,8 @@ test "type deduction for array subscript expression" { } test "sentinel element count towards the ABI size calculation" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -482,7 +482,7 @@ test "sentinel element count towards the ABI size calculation" { const S = struct { fn doTheTest() !void { - const T = packed struct { + const T = extern struct { fill_pre: u8 = 0x55, data: [0:0]u8 = undefined, fill_post: u8 = 0xAA, @@ -500,7 +500,7 @@ test "sentinel element count towards the ABI size calculation" { } test "zero-sized array with recursive type definition" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -525,7 +525,7 @@ test "zero-sized array with recursive type definition" { } test "type coercion of anon struct literal to array" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -561,8 +561,8 @@ test "type coercion of anon struct literal to array" { } test "type coercion of pointer to anon struct literal to pointer to array" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index ac6bee8c73..c78388ac8d 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -132,7 +132,6 @@ test "bitcast generates a temporary value" { } test "@bitCast packed structs at runtime and comptime" { - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -170,7 +169,6 @@ test "@bitCast packed structs at runtime and comptime" { } test "@bitCast extern structs at runtime and comptime" { - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -205,7 +203,6 @@ test "@bitCast extern structs at runtime and comptime" { } test "bitcast packed struct to integer and back" { - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -246,7 +243,6 @@ test "implicit cast to error union by returning" { } test "bitcast packed struct literal to byte" { - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -261,7 +257,6 @@ test "bitcast packed struct literal to byte" { } test "comptime bitcast used in expression has the correct type" { - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; diff --git a/test/behavior/sizeof_and_typeof.zig b/test/behavior/sizeof_and_typeof.zig index f359fe458e..a405309244 100644 --- a/test/behavior/sizeof_and_typeof.zig +++ b/test/behavior/sizeof_and_typeof.zig @@ -210,13 +210,13 @@ test "branching logic inside @TypeOf" { } test "@bitSizeOf" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage1) return error.SkipZigTest; try expect(@bitSizeOf(u2) == 2); try expect(@bitSizeOf(u8) == @sizeOf(u8) * 8); try expect(@bitSizeOf(struct { a: u2, - }) == 8); + }) == 2); try expect(@bitSizeOf(packed struct { a: u2, }) == 2); diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 5f46894fda..e3b0bb193b 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -268,25 +268,6 @@ test "struct field init with catch" { comptime try S.doTheTest(); } -test "packed struct field alignment" { - if (builtin.object_format == .c) return error.SkipZigTest; - - const Stage1 = struct { - var baz: packed struct { - a: u32, - b: u32, - } = undefined; - }; - const Stage2 = struct { - var baz: packed struct { - a: u32, - b: u32 align(1), - } = undefined; - }; - const S = if (builtin.zig_backend != .stage1) Stage2 else Stage1; - try expect(@TypeOf(&S.baz.b) == *align(1) u32); -} - const blah: packed struct { a: u3, b: u3, @@ -687,48 +668,52 @@ test "default struct initialization fields" { try expect(1239 == x.a + x.b); } -// TODO revisit this test when doing https://github.com/ziglang/zig/issues/1512 test "packed array 24bits" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage1) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; comptime { try expect(@sizeOf([9]Foo32Bits) == 9 * 4); - try expect(@sizeOf(FooArray24Bits) == 2 + 2 * 4 + 2); + try expect(@sizeOf(FooArray24Bits) == @sizeOf(u96)); } var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1); - bytes[bytes.len - 1] = 0xaa; + bytes[bytes.len - 1] = 0xbb; const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0]; try expect(ptr.a == 0); - try expect(ptr.b[0].field == 0); - try expect(ptr.b[1].field == 0); + try expect(ptr.b0.field == 0); + try expect(ptr.b1.field == 0); try expect(ptr.c == 0); ptr.a = maxInt(u16); try expect(ptr.a == maxInt(u16)); - try expect(ptr.b[0].field == 0); - try expect(ptr.b[1].field == 0); + try expect(ptr.b0.field == 0); + try expect(ptr.b1.field == 0); try expect(ptr.c == 0); - ptr.b[0].field = maxInt(u24); + ptr.b0.field = maxInt(u24); try expect(ptr.a == maxInt(u16)); - try expect(ptr.b[0].field == maxInt(u24)); - try expect(ptr.b[1].field == 0); + try expect(ptr.b0.field == maxInt(u24)); + try expect(ptr.b1.field == 0); try expect(ptr.c == 0); - ptr.b[1].field = maxInt(u24); + ptr.b1.field = maxInt(u24); try expect(ptr.a == maxInt(u16)); - try expect(ptr.b[0].field == maxInt(u24)); - try expect(ptr.b[1].field == maxInt(u24)); + try expect(ptr.b0.field == maxInt(u24)); + try expect(ptr.b1.field == maxInt(u24)); try expect(ptr.c == 0); ptr.c = maxInt(u16); try expect(ptr.a == maxInt(u16)); - try expect(ptr.b[0].field == maxInt(u24)); - try expect(ptr.b[1].field == maxInt(u24)); + try expect(ptr.b0.field == maxInt(u24)); + try expect(ptr.b1.field == maxInt(u24)); try expect(ptr.c == maxInt(u16)); - try expect(bytes[bytes.len - 1] == 0xaa); + try expect(bytes[bytes.len - 1] == 0xbb); } const Foo32Bits = packed struct { @@ -738,12 +723,16 @@ const Foo32Bits = packed struct { const FooArray24Bits = packed struct { a: u16, - b: [2]Foo32Bits, + b0: Foo32Bits, + b1: Foo32Bits, c: u16, }; test "aligned array of packed struct" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO comptime { try expect(@sizeOf(FooStructAligned) == 2); @@ -769,7 +758,10 @@ const FooArrayOfAligned = packed struct { }; test "pointer to packed struct member in a stack variable" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = packed struct { a: u2, @@ -783,32 +775,12 @@ test "pointer to packed struct member in a stack variable" { try expect(s.b == 2); } -test "non-byte-aligned array inside packed struct" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - - const Foo = packed struct { - a: bool, - b: [0x16]u8, - }; - const S = struct { - fn bar(slice: []const u8) !void { - try expectEqualSlices(u8, slice, "abcdefghijklmnopqurstu"); - } - fn doTheTest() !void { - var foo = Foo{ - .a = true, - .b = "abcdefghijklmnopqurstu".*, - }; - const value = foo.b; - try bar(&value); - } - }; - try S.doTheTest(); - comptime try S.doTheTest(); -} - test "packed struct with u0 field access" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO const S = packed struct { f0: u0, @@ -818,7 +790,11 @@ test "packed struct with u0 field access" { } test "access to global struct fields" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO g_foo.bar.value = 42; try expect(g_foo.bar.value == 42); @@ -839,26 +815,32 @@ const S0 = struct { var g_foo: S0 = S0.init(); test "packed struct with fp fields" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO const S = packed struct { - data: [3]f32, + data0: f32, + data1: f32, + data2: f32, pub fn frob(self: *@This()) void { - self.data[0] += self.data[1] + self.data[2]; - self.data[1] += self.data[0] + self.data[2]; - self.data[2] += self.data[0] + self.data[1]; + self.data0 += self.data1 + self.data2; + self.data1 += self.data0 + self.data2; + self.data2 += self.data0 + self.data1; } }; var s: S = undefined; - s.data[0] = 1.0; - s.data[1] = 2.0; - s.data[2] = 3.0; + s.data0 = 1.0; + s.data1 = 2.0; + s.data2 = 3.0; s.frob(); - try expectEqual(@as(f32, 6.0), s.data[0]); - try expectEqual(@as(f32, 11.0), s.data[1]); - try expectEqual(@as(f32, 20.0), s.data[2]); + try expect(@as(f32, 6.0) == s.data0); + try expect(@as(f32, 11.0) == s.data1); + try expect(@as(f32, 20.0) == s.data2); } test "fn with C calling convention returns struct by value" { @@ -906,7 +888,11 @@ test "non-packed struct with u128 entry in union" { } test "packed struct field passed to generic function" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO const S = struct { const P = packed struct { @@ -1046,8 +1032,8 @@ test "struct with union field" { var True = Value{ .kind = .{ .Bool = true }, }; - try expectEqual(@as(u32, 2), True.ref); - try expectEqual(true, True.kind.Bool); + try expect(@as(u32, 2) == True.ref); + try expect(True.kind.Bool); } test "type coercion of anon struct literal to struct" { diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index 8ba627e686..d436de36a1 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -274,7 +274,7 @@ const TestStruct = struct { }; test "type info: packed struct info" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage1) return error.SkipZigTest; try testPackedStruct(); comptime try testPackedStruct(); @@ -286,19 +286,19 @@ fn testPackedStruct() !void { try expect(struct_info.Struct.is_tuple == false); try expect(struct_info.Struct.layout == .Packed); try expect(struct_info.Struct.fields.len == 4); - try expect(struct_info.Struct.fields[0].alignment == 2 * @alignOf(usize)); - try expect(struct_info.Struct.fields[2].field_type == *TestPackedStruct); + try expect(struct_info.Struct.fields[0].alignment == 0); + try expect(struct_info.Struct.fields[2].field_type == f32); try expect(struct_info.Struct.fields[2].default_value == null); try expect(@ptrCast(*const u32, struct_info.Struct.fields[3].default_value.?).* == 4); - try expect(struct_info.Struct.fields[3].alignment == 1); + try expect(struct_info.Struct.fields[3].alignment == 0); try expect(struct_info.Struct.decls.len == 2); try expect(struct_info.Struct.decls[0].is_pub); } const TestPackedStruct = packed struct { - fieldA: usize align(2 * @alignOf(usize)), + fieldA: usize, fieldB: void, - fieldC: *Self, + fieldC: f32, fieldD: u32 = 4, pub fn foo(self: *const Self) void { @@ -329,6 +329,7 @@ test "type info: function type info" { // wasm doesn't support align attributes on functions if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest; + try testFunction(); comptime try testFunction(); } -- cgit v1.2.3 From 91fbcf70935118c0667031ba7ae76fa0e75d80cc Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Sun, 27 Feb 2022 13:14:57 +0100 Subject: stage2 ARM: enable more behavior tests --- src/arch/arm/CodeGen.zig | 1 + test/behavior/align.zig | 2 -- test/behavior/array.zig | 3 --- test/behavior/basic.zig | 7 ------- test/behavior/bitcast.zig | 6 ------ test/behavior/bitreverse.zig | 1 - test/behavior/bugs/3367.zig | 1 - test/behavior/bugs/3586.zig | 1 - test/behavior/bugs/4560.zig | 1 - test/behavior/bugs/704.zig | 1 - test/behavior/cast.zig | 3 --- test/behavior/defer.zig | 2 -- test/behavior/enum.zig | 21 --------------------- test/behavior/error.zig | 7 ------- test/behavior/fn.zig | 15 --------------- test/behavior/for.zig | 3 --- test/behavior/generics.zig | 6 ------ test/behavior/if.zig | 3 --- test/behavior/slice.zig | 2 -- test/behavior/struct.zig | 7 ------- test/behavior/this.zig | 1 - test/behavior/try.zig | 2 -- test/behavior/type_info.zig | 1 - test/behavior/undefined.zig | 1 - test/behavior/union.zig | 20 -------------------- test/behavior/usingnamespace.zig | 4 ---- test/behavior/void.zig | 1 - 27 files changed, 1 insertion(+), 122 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index f4e97fa8b1..51b2e7f1a8 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -1359,6 +1359,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { const base_mcv: MCValue = switch (slice_mcv) { .stack_offset => |off| .{ .register = try self.copyToTmpRegister(slice_ptr_field_type, .{ .stack_offset = off + 4 }) }, + .stack_argument_offset => |off| .{ .register = try self.copyToTmpRegister(slice_ptr_field_type, .{ .stack_argument_offset = off + 4 }) }, else => return self.fail("TODO slice_elem_val when slice is {}", .{slice_mcv}), }; self.register_manager.freezeRegs(&.{base_mcv.register}); diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 28dcd7a508..acdf484b15 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -6,8 +6,6 @@ const native_arch = builtin.target.cpu.arch; var foo: u8 align(4) = 100; test "global variable alignment" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); comptime try expect(@TypeOf(&foo) == *align(4) u8); { diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 2d4d1368f5..1d6a149560 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -70,8 +70,6 @@ test "array literal with explicit type" { } test "array literal with inferred length" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - const hex_mult = [_]u16{ 4096, 256, 16, 1 }; try expect(hex_mult.len == 4); @@ -142,7 +140,6 @@ test "array with sentinels" { test "void arrays" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array: [4]void = undefined; array[0] = void{}; diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index c36fa0c921..010e44db73 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -120,14 +120,12 @@ test "return string from function" { test "hex escape" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try expect(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello")); } test "multiline string" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const s1 = \\one @@ -140,7 +138,6 @@ test "multiline string" { test "multiline string comments at start" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const s1 = //\\one @@ -153,7 +150,6 @@ test "multiline string comments at start" { test "multiline string comments at end" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const s1 = \\one @@ -166,7 +162,6 @@ test "multiline string comments at end" { test "multiline string comments in middle" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const s1 = \\one @@ -179,7 +174,6 @@ test "multiline string comments in middle" { test "multiline string comments at multiple places" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const s1 = \\one @@ -198,7 +192,6 @@ test "string concatenation" { test "array mult operator" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try expect(mem.eql(u8, "ab" ** 5, "ababababab")); } diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index c78388ac8d..835ed734ef 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -76,7 +76,6 @@ fn conv_uN(comptime N: usize, x: std.meta.Int(.unsigned, N)) std.meta.Int(.signe test "nested bitcast" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn moo(x: isize) !void { @@ -96,7 +95,6 @@ test "nested bitcast" { test "@bitCast enum to its integer type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const SOCK = enum(c_int) { A, @@ -116,7 +114,6 @@ test "@bitCast enum to its integer type" { // issue #3010: compiler segfault test "bitcast literal [4]u8 param to u32" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const ip = @bitCast(u32, [_]u8{ 255, 255, 255, 255 }); try expect(ip == maxInt(u32)); @@ -124,7 +121,6 @@ test "bitcast literal [4]u8 param to u32" { test "bitcast generates a temporary value" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var y = @as(u16, 0x55AA); const x = @bitCast(u16, @bitCast([2]u8, y)); @@ -247,7 +243,6 @@ test "bitcast packed struct literal to byte" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const Foo = packed struct { value: u8, @@ -261,7 +256,6 @@ test "comptime bitcast used in expression has the correct type" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const Foo = packed struct { value: u8, diff --git a/test/behavior/bitreverse.zig b/test/behavior/bitreverse.zig index 28980cccf3..11179b964a 100644 --- a/test/behavior/bitreverse.zig +++ b/test/behavior/bitreverse.zig @@ -7,7 +7,6 @@ test "@bitReverse large exotic integer" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // Currently failing on stage1 for big-endian targets if (builtin.zig_backend == .stage1) return error.SkipZigTest; diff --git a/test/behavior/bugs/3367.zig b/test/behavior/bugs/3367.zig index 6468498ab6..4509283457 100644 --- a/test/behavior/bugs/3367.zig +++ b/test/behavior/bugs/3367.zig @@ -12,7 +12,6 @@ const Mixin = struct { test "container member access usingnamespace decls" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var foo = Foo{}; foo.two(); } diff --git a/test/behavior/bugs/3586.zig b/test/behavior/bugs/3586.zig index f7266e9918..e61ed19616 100644 --- a/test/behavior/bugs/3586.zig +++ b/test/behavior/bugs/3586.zig @@ -7,7 +7,6 @@ const Container = struct { }; test "fixed" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var ctr = Container{ diff --git a/test/behavior/bugs/4560.zig b/test/behavior/bugs/4560.zig index b3e40dd7f8..30d3677920 100644 --- a/test/behavior/bugs/4560.zig +++ b/test/behavior/bugs/4560.zig @@ -2,7 +2,6 @@ const std = @import("std"); const builtin = @import("builtin"); test "fixed" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var s: S = .{ diff --git a/test/behavior/bugs/704.zig b/test/behavior/bugs/704.zig index 352f61ac62..f15ddab726 100644 --- a/test/behavior/bugs/704.zig +++ b/test/behavior/bugs/704.zig @@ -6,7 +6,6 @@ const xxx = struct { } }; test "bug 704" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var x: xxx = undefined; diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index d7071f64df..e237fa8439 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1067,7 +1067,6 @@ test "implicit cast *[0]T to E![]const u8" { var global_array: [4]u8 = undefined; test "cast from array reference to fn: comptime fn ptr" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const f = @ptrCast(*const fn () callconv(.C) void, &global_array); @@ -1075,7 +1074,6 @@ test "cast from array reference to fn: comptime fn ptr" { } test "cast from array reference to fn: runtime fn ptr" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var f = @ptrCast(*const fn () callconv(.C) void, &global_array); @@ -1100,7 +1098,6 @@ test "*const [N]null u8 to ?[]const u8" { } test "cast between [*c]T and ?[*:0]T on fn parameter" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { diff --git a/test/behavior/defer.zig b/test/behavior/defer.zig index 360d6e14bb..236b37a51c 100644 --- a/test/behavior/defer.zig +++ b/test/behavior/defer.zig @@ -5,7 +5,6 @@ const expectEqual = std.testing.expectEqual; const expectError = std.testing.expectError; test "break and continue inside loop inside defer expression" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; testBreakContInDefer(10); @@ -24,7 +23,6 @@ fn testBreakContInDefer(x: usize) void { } test "defer and labeled break" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var i = @as(usize, 0); diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index d0f62842c1..8b56503ec3 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -11,7 +11,6 @@ fn shouldEqual(n: Number, expected: u3) !void { } test "enum to int" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try shouldEqual(Number.Zero, 0); @@ -559,7 +558,6 @@ const ValueCount257 = enum { }; test "enum sizes" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; comptime { @@ -571,7 +569,6 @@ test "enum sizes" { } test "enum literal equality" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const x = .hi; @@ -583,7 +580,6 @@ test "enum literal equality" { } test "enum literal cast to enum" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Color = enum { Auto, Off, On }; @@ -594,7 +590,6 @@ test "enum literal cast to enum" { } test "peer type resolution with enum literal" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Items = enum { one, two }; @@ -675,7 +670,6 @@ test "non-exhaustive enum" { } test "empty non-exhaustive enum" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const S = struct { @@ -741,7 +735,6 @@ const EnumWithTagValues = enum(u4) { D = 1 << 3, }; test "enum with tag values don't require parens" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(@enumToInt(EnumWithTagValues.C) == 0b0100); @@ -760,7 +753,6 @@ const MultipleChoice2 = enum(u32) { }; test "cast integer literal to enum" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(@intToEnum(MultipleChoice2, 0) == MultipleChoice2.Unspecified1); @@ -795,7 +787,6 @@ const Small2 = enum(u2) { One, Two }; const Small = enum(u2) { One, Two, Three, Four }; test "set enum tag type" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; { @@ -811,7 +802,6 @@ test "set enum tag type" { } test "casting enum to its tag type" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try testCastEnumTag(Small2.Two); @@ -823,7 +813,6 @@ fn testCastEnumTag(value: Small2) !void { } test "enum with 1 field but explicit tag type should still have the tag type" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Enum = enum(u8) { @@ -833,7 +822,6 @@ test "enum with 1 field but explicit tag type should still have the tag type" { } test "signed integer as enum tag" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const SignedEnum = enum(i2) { @@ -848,7 +836,6 @@ test "signed integer as enum tag" { } test "enum with one member and custom tag type" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const E = enum(u2) { @@ -862,7 +849,6 @@ test "enum with one member and custom tag type" { } test "enum with one member and u1 tag type @enumToInt" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Enum = enum(u1) { @@ -872,7 +858,6 @@ test "enum with one member and u1 tag type @enumToInt" { } test "enum with comptime_int tag type" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Enum = enum(comptime_int) { @@ -884,7 +869,6 @@ test "enum with comptime_int tag type" { } test "enum with one member default to u0 tag type" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const E0 = enum { X }; @@ -903,7 +887,6 @@ fn doALoopThing(id: EnumWithOneMember) void { } test "comparison operator on enum with one member is comptime known" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; doALoopThing(EnumWithOneMember.Eof); @@ -911,7 +894,6 @@ test "comparison operator on enum with one member is comptime known" { const State = enum { Start }; test "switch on enum with one member is comptime known" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var state = State.Start; @@ -922,7 +904,6 @@ test "switch on enum with one member is comptime known" { } test "method call on an enum" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const S = struct { @@ -1117,7 +1098,6 @@ test "tag name with assigned enum values" { } test "@tagName on enum literals" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(mem.eql(u8, @tagName(.FooBar), "FooBar")); @@ -1184,7 +1164,6 @@ fn getC(data: *const BitFieldOfEnums) C { } test "enum literal in array literal" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Items = enum { one, two }; diff --git a/test/behavior/error.zig b/test/behavior/error.zig index e346e6a82a..ab58874c34 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -6,7 +6,6 @@ const expectEqual = std.testing.expectEqual; const mem = std.mem; test "error values" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const a = @errorToInt(error.err1); @@ -15,7 +14,6 @@ test "error values" { } test "redefinition of error values allowed" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; shouldBeNotEqual(error.AnError, error.SecondError); @@ -39,7 +37,6 @@ fn errBinaryOperatorG(x: bool) anyerror!isize { } test "empty error union" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const x = error{} || error{}; @@ -98,7 +95,6 @@ fn makeANonErr() anyerror!i32 { } test "syntax: optional operator in front of error union operator" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; comptime { @@ -157,7 +153,6 @@ test "implicit cast to optional to error union to return result loc" { } test "error: fn returning empty error set can be passed as fn returning any error" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; entry(); @@ -178,7 +173,6 @@ fn bar2() (error{}!void) {} test "error union type " { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO @@ -197,7 +191,6 @@ fn testErrorUnionType() !void { test "error set type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index c4779379c5..71602aa698 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -5,7 +5,6 @@ const expect = testing.expect; const expectEqual = testing.expectEqual; test "params" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(testParamsAdd(22, 11) == 33); @@ -15,7 +14,6 @@ fn testParamsAdd(a: i32, b: i32) i32 { } test "local variables" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; testLocVars(2); @@ -26,7 +24,6 @@ fn testLocVars(b: i32) void { } test "mutable local variables" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var zero: i32 = 0; @@ -40,7 +37,6 @@ test "mutable local variables" { } test "separate block scopes" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; { @@ -59,14 +55,12 @@ fn @"weird function name"() i32 { return 1234; } test "weird function name" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(@"weird function name"() == 1234); } test "assign inline fn to const variable" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const a = inlineFn; @@ -86,7 +80,6 @@ fn outer(y: u32) *const fn (u32) u32 { } test "return inner function which references comptime variable of outer function" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; @@ -156,7 +149,6 @@ test "inline function call that calls optional function pointer, return pointer } test "implicit cast function unreachable return" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; wantsFnWithVoid(fnWithUnreachable); @@ -209,7 +201,6 @@ test "function with complex callconv and return type expressions" { } test "pass by non-copying value" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3); @@ -238,7 +229,6 @@ fn addPointCoordsVar(pt: anytype) !i32 { } test "pass by non-copying value as method" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var pt = Point2{ .x = 1, .y = 2 }; @@ -255,7 +245,6 @@ const Point2 = struct { }; test "pass by non-copying value as method, which is generic" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var pt = Point3{ .x = 1, .y = 2 }; @@ -273,7 +262,6 @@ const Point3 = struct { }; test "pass by non-copying value as method, at comptime" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; comptime { @@ -325,7 +313,6 @@ fn voidFun(a: i32, b: void, c: i32, d: void) !void { } test "call function with empty string" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; acceptsString(""); @@ -362,7 +349,6 @@ fn fn4() u32 { } test "number literal as an argument" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try numberLiteralArg(3); @@ -395,7 +381,6 @@ test "function call with anon list literal" { } test "ability to give comptime types and non comptime types to same parameter" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const S = struct { diff --git a/test/behavior/for.zig b/test/behavior/for.zig index 011363bffd..8f465eb3de 100644 --- a/test/behavior/for.zig +++ b/test/behavior/for.zig @@ -21,7 +21,6 @@ test "continue in for loop" { } test "break from outer for loop" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try testBreakOuter(); @@ -41,7 +40,6 @@ fn testBreakOuter() !void { } test "continue outer for loop" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try testContinueOuter(); @@ -61,7 +59,6 @@ fn testContinueOuter() !void { } test "ignore lval with underscore (for loop)" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; for ([_]void{}) |_, i| { diff --git a/test/behavior/generics.zig b/test/behavior/generics.zig index e76cca4e1f..c73ae26e28 100644 --- a/test/behavior/generics.zig +++ b/test/behavior/generics.zig @@ -5,7 +5,6 @@ const expect = testing.expect; const expectEqual = testing.expectEqual; test "one param, explicit comptime" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var x: usize = 0; @@ -43,7 +42,6 @@ fn add(comptime a: i32, b: i32) i32 { const the_max = max(u32, 1234, 5678); test "compile time generic eval" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(the_max == 5678); @@ -144,7 +142,6 @@ pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) type { } test "const decls in struct" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(GenericDataThing(3).count_plus_one == 4); @@ -156,7 +153,6 @@ fn GenericDataThing(comptime count: isize) type { } test "use generic param in generic param" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(aGenericFn(i32, 3, 4) == 7); @@ -201,7 +197,6 @@ test "generic fn keeps non-generic parameter types" { } test "array of generic fns" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; @@ -223,7 +218,6 @@ fn foo2(arg: anytype) bool { test "generic struct" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var a1 = GenNode(i32){ .value = 13, diff --git a/test/behavior/if.zig b/test/behavior/if.zig index 068f3bdd21..54ee5338af 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -30,7 +30,6 @@ fn firstEqlThird(a: i32, b: i32, c: i32) void { } test "else if expression" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(elseIfExpressionF(1) == 1); @@ -67,7 +66,6 @@ test "unwrap mutable global var" { } test "labeled break inside comptime if inside runtime if" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var answer: i32 = 0; @@ -81,7 +79,6 @@ test "labeled break inside comptime if inside runtime if" { } test "const result loc, runtime if cond, else unreachable" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Num = enum { One, Two }; diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index e746535d97..c6405fd168 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -220,7 +220,6 @@ test "compile time slice of pointer to hard coded address" { test "slice string literal has correct type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; comptime { try expect(@TypeOf("aoeu"[0..]) == *const [4:0]u8); @@ -565,7 +564,6 @@ test "array concat of slices gives slice" { } test "slice bounds in comptime concatenation" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const bs = comptime blk: { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 1da2b0373d..47a71ae68e 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -215,7 +215,6 @@ fn makeBar2(x: i32, y: i32) Bar { test "call method with mutable reference to struct with no fields" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doC(s: *const @This()) bool { @@ -343,7 +342,6 @@ test "pass slice of empty struct to fn" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1); } @@ -369,7 +367,6 @@ test "self-referencing struct via array member" { test "empty struct method call" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const es = EmptyStruct{}; try expect(es.method() == 1234); @@ -567,7 +564,6 @@ test "implicit cast packed struct field to const ptr" { test "zero-bit field in packed struct" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = packed struct { @@ -645,7 +641,6 @@ test "default struct initialization fields" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { a: i32 = 1234, @@ -776,7 +771,6 @@ test "pointer to packed struct member in a stack variable" { test "packed struct with u0 field access" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -915,7 +909,6 @@ test "anonymous struct literal syntax" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { const Point = struct { diff --git a/test/behavior/this.zig b/test/behavior/this.zig index 49b7ca69d9..a284310b1a 100644 --- a/test/behavior/this.zig +++ b/test/behavior/this.zig @@ -21,7 +21,6 @@ fn add(x: i32, y: i32) i32 { } test "this refer to module call private fn" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect(module.add(1, 2) == 3); diff --git a/test/behavior/try.zig b/test/behavior/try.zig index cd8b03afab..898c596ade 100644 --- a/test/behavior/try.zig +++ b/test/behavior/try.zig @@ -25,7 +25,6 @@ fn returnsTen() anyerror!i32 { } test "try without vars" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const result1 = if (failIfTrue(true)) 1 else |_| @as(i32, 2); @@ -44,7 +43,6 @@ fn failIfTrue(ok: bool) anyerror!void { } test "try then not executed with assignment" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (failIfTrue(true)) { diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index c4517ac277..8105e9c02a 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -289,7 +289,6 @@ fn testUnion() !void { } test "type info: struct info" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try testStruct(); diff --git a/test/behavior/undefined.zig b/test/behavior/undefined.zig index dcea219593..abfbcc23bc 100644 --- a/test/behavior/undefined.zig +++ b/test/behavior/undefined.zig @@ -77,7 +77,6 @@ test "assign undefined to struct with method" { } test "type name of undefined" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const x = undefined; diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 91bd783ce2..6044bf983c 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -43,8 +43,6 @@ fn setInt(foo: *Foo, x: i32) void { } test "comptime union field access" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - comptime { var foo = Foo{ .int = 0 }; try expect(foo.int == 0); @@ -75,14 +73,10 @@ const ExternPtrOrInt = extern union { int: u64, }; test "extern union size" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - comptime try expect(@sizeOf(ExternPtrOrInt) == 8); } test "0-sized extern union definition" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - const U = extern union { a: void, const f = 1; @@ -112,8 +106,6 @@ const err = @as(anyerror!Agg, Agg{ const array = [_]Value{ v1, v2, v1, v2 }; test "unions embedded in aggregate types" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - switch (array[1]) { Value.Array => |arr| try expect(arr[4] == 3), else => unreachable, @@ -125,8 +117,6 @@ test "unions embedded in aggregate types" { } test "access a member of tagged union with conflicting enum tag name" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - const Bar = union(enum) { A: A, B: B, @@ -169,8 +159,6 @@ const TaggedUnionWithPayload = union(enum) { }; test "union alignment" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - comptime { try expect(@alignOf(AlignTestTaggedUnion) >= @alignOf([9]u8)); try expect(@alignOf(AlignTestTaggedUnion) >= @alignOf(u64)); @@ -268,8 +256,6 @@ fn testCastUnionToTag() !void { } test "union field access gives the enum values" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - try expect(TheUnion.A == TheTag.A); try expect(TheUnion.B == TheTag.B); try expect(TheUnion.C == TheTag.C); @@ -343,8 +329,6 @@ const PackedPtrOrInt = packed union { int: u64, }; test "packed union size" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - comptime try expect(@sizeOf(PackedPtrOrInt) == 8); } @@ -352,8 +336,6 @@ const ZeroBits = union { OnlyField: void, }; test "union with only 1 field which is void should be zero bits" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - comptime try expect(@sizeOf(ZeroBits) == 0); } @@ -411,8 +393,6 @@ test "union with only 1 field casted to its enum type" { } test "union with one member defaults to u0 tag type" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - const U0 = union(enum) { X: u32, }; diff --git a/test/behavior/usingnamespace.zig b/test/behavior/usingnamespace.zig index 611b9888fa..8caf2af27c 100644 --- a/test/behavior/usingnamespace.zig +++ b/test/behavior/usingnamespace.zig @@ -11,7 +11,6 @@ const C = struct { }; test "basic usingnamespace" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try std.testing.expect(C.B == bool); @@ -24,7 +23,6 @@ fn Foo(comptime T: type) type { } test "usingnamespace inside a generic struct" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const std2 = Foo(std); @@ -38,7 +36,6 @@ usingnamespace struct { }; test "usingnamespace does not redeclare an imported variable" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; comptime try std.testing.expect(@This().foo == 42); @@ -57,7 +54,6 @@ fn privateFunction() bool { } test { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; _ = @import("usingnamespace/import_segregation.zig"); diff --git a/test/behavior/void.zig b/test/behavior/void.zig index 800dbb1b00..b1efda23e4 100644 --- a/test/behavior/void.zig +++ b/test/behavior/void.zig @@ -43,7 +43,6 @@ test "void optional" { } test "void array as a local variable initializer" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var x = [_]void{{}} ** 1004; -- cgit v1.2.3 From 1bf8da19e1b58159b27033d415b7289cf455b870 Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Sun, 27 Feb 2022 21:38:09 +0100 Subject: stage2 ARM: implement slice and array_to_slice --- src/arch/arm/CodeGen.zig | 33 ++++++++++++++++++++++++++++----- test/behavior/array.zig | 2 -- test/behavior/cast.zig | 3 --- test/behavior/if.zig | 1 - test/behavior/slice.zig | 2 -- test/behavior/while.zig | 1 - 6 files changed, 28 insertions(+), 14 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 51b2e7f1a8..6cd4a1fd9f 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -433,7 +433,9 @@ fn gen(self: *Self) !void { }); // exitlude jumps - if (self.exitlude_jump_relocs.items.len == 1) { + const only_one_exitlude_jump = self.exitlude_jump_relocs.items.len == 1 and + self.exitlude_jump_relocs.items[0] == self.mir_instructions.len - 1; + if (only_one_exitlude_jump) { // There is only one relocation. Hence, // this relocation must be at the end of // the code. Therefore, we can just delete @@ -1066,7 +1068,17 @@ fn airMax(self: *Self, inst: Air.Inst.Index) !void { fn airSlice(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ptr = try self.resolveInst(bin_op.lhs); + const ptr_ty = self.air.typeOf(bin_op.lhs); + const len = try self.resolveInst(bin_op.rhs); + const len_ty = self.air.typeOf(bin_op.rhs); + + const stack_offset = try self.allocMem(inst, 8, 8); + try self.genSetStack(ptr_ty, stack_offset + 4, ptr); + try self.genSetStack(len_ty, stack_offset, len); + break :result MCValue{ .stack_offset = stack_offset }; + }; return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -3855,9 +3867,17 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airArrayToSlice for {}", .{ - self.target.cpu.arch, - }); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ptr_ty = self.air.typeOf(ty_op.operand); + const ptr = try self.resolveInst(ty_op.operand); + const array_ty = ptr_ty.childType(); + const array_len = @intCast(u32, array_ty.arrayLenIncludingSentinel()); + + const stack_offset = try self.allocMem(inst, 8, 8); + try self.genSetStack(ptr_ty, stack_offset + 4, ptr); + try self.genSetStack(Type.initTag(.usize), stack_offset, .{ .immediate = array_len }); + break :result MCValue{ .stack_offset = stack_offset }; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -4078,6 +4098,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { } switch (typed_value.ty.zigTypeTag()) { + .Array => { + return self.lowerUnnamedConst(typed_value); + }, .Pointer => switch (typed_value.ty.ptrSize()) { .Slice => { return self.lowerUnnamedConst(typed_value); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 1d6a149560..58c676b7b8 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -49,7 +49,6 @@ fn getArrayLen(a: []const u32) usize { test "array init with mult" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const a = 'a'; var i: [8]u8 = [2]u8{ a, 'b' } ** 4; @@ -98,7 +97,6 @@ test "array literal with specified size" { test "array len field" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var arr = [4]u8{ 0, 0, 0, 0 }; var ptr = &arr; diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index e237fa8439..819739083b 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -273,7 +273,6 @@ test "*const ?[*]const T to [*c]const [*c]const T" { test "array coersion to undefined at runtime" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @setRuntimeSafety(true); @@ -337,7 +336,6 @@ test "peer type unsigned int to signed" { test "expected [*c]const u8, found [*:0]const u8" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var a: [*:0]const u8 = "hello"; var b: [*c]const u8 = a; @@ -648,7 +646,6 @@ test "peer cast *[0]T to []const T" { test "peer cast *[N]T to [*]T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var array = [4:99]i32{ 1, 2, 3, 4 }; diff --git a/test/behavior/if.zig b/test/behavior/if.zig index 54ee5338af..cf7a932ccb 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -4,7 +4,6 @@ const expect = std.testing.expect; const expectEqual = std.testing.expectEqual; test "if statements" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; shouldBeEqual(1, 1); diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index c6405fd168..992a187a3e 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -257,7 +257,6 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 { test "C pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf"; var len: u32 = 10; @@ -356,7 +355,6 @@ test "empty array to slice" { test "@ptrCast slice to pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest() !void { diff --git a/test/behavior/while.zig b/test/behavior/while.zig index 86724d166a..03670d28a7 100644 --- a/test/behavior/while.zig +++ b/test/behavior/while.zig @@ -249,7 +249,6 @@ fn returnTrue() bool { test "return with implicit cast from while loop" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; returnWithImplicitCastFromWhileLoopTest() catch unreachable; -- cgit v1.2.3 From cfbc3537ef0b3a73d5b8fdd358cf3bb831935861 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 28 Feb 2022 19:54:13 +0100 Subject: x64: pass more behavior tests --- src/arch/x86_64/CodeGen.zig | 4 ---- test/behavior/align.zig | 5 +++-- test/behavior/alignof.zig | 2 -- test/behavior/array.zig | 1 - test/behavior/basic.zig | 2 -- test/behavior/bitcast.zig | 3 --- test/behavior/bitreverse.zig | 1 - test/behavior/bugs/1381.zig | 1 - test/behavior/bugs/1735.zig | 1 - test/behavior/bugs/4954.zig | 1 - test/behavior/cast.zig | 21 +-------------------- test/behavior/defer.zig | 1 - test/behavior/enum.zig | 6 ------ test/behavior/fn.zig | 1 - test/behavior/if.zig | 1 - test/behavior/ir_block_deps.zig | 1 - test/behavior/namespace_depends_on_compile_var.zig | 1 - test/behavior/optional.zig | 3 --- test/behavior/struct.zig | 1 - test/behavior/try.zig | 1 - test/behavior/underscore.zig | 1 - test/behavior/while.zig | 4 ---- 22 files changed, 4 insertions(+), 59 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 3620995514..1c86b794d7 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -4839,10 +4839,6 @@ fn genInlineMemset( try self.register_manager.getReg(.rax, null); const abi_size = ty.abiSize(self.target.*); - if (stack_offset > 128) { - return self.fail("TODO inline memset with large stack offset", .{}); - } - const negative_offset = @bitCast(u32, -stack_offset); // We are actually counting `abi_size` bytes; however, we reuse the index register diff --git a/test/behavior/align.zig b/test/behavior/align.zig index acdf484b15..4b35e94d56 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -124,7 +124,7 @@ fn testBytesAlign(b: u8) !void { test "@alignCast slices" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array align(4) = [_]u32{ 1, 1 }; const slice = array[0..]; @@ -140,7 +140,8 @@ fn sliceExpects4(slice: []align(4) u32) void { test "return error union with 128-bit integer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try expect(3 == try give()); } diff --git a/test/behavior/alignof.zig b/test/behavior/alignof.zig index 5a49146694..b065e4b87f 100644 --- a/test/behavior/alignof.zig +++ b/test/behavior/alignof.zig @@ -14,7 +14,6 @@ test "@alignOf(T) before referencing T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; comptime try expect(@alignOf(Foo) != maxInt(usize)); if (native_arch == .x86_64) { comptime try expect(@alignOf(Foo) == 4); @@ -23,7 +22,6 @@ test "@alignOf(T) before referencing T" { test "comparison of @alignOf(T) against zero" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; { const T = struct { x: u32 }; try expect(!(@alignOf(T) == 0)); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 58c676b7b8..eb41d791e5 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -348,7 +348,6 @@ test "array literal as argument to function" { test "double nested array to const slice cast in array literal" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index 010e44db73..f9528319ac 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -287,7 +287,6 @@ fn fB() []const u8 { test "call function pointer in struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; try expect(mem.eql(u8, f3(true), "a")); @@ -814,7 +813,6 @@ test "if expression type coercion" { } test "discarding the result of various expressions" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index 835ed734ef..2b3c19da2a 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -167,7 +167,6 @@ test "@bitCast packed structs at runtime and comptime" { test "@bitCast extern structs at runtime and comptime" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -241,7 +240,6 @@ test "implicit cast to error union by returning" { test "bitcast packed struct literal to byte" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Foo = packed struct { @@ -254,7 +252,6 @@ test "bitcast packed struct literal to byte" { test "comptime bitcast used in expression has the correct type" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Foo = packed struct { diff --git a/test/behavior/bitreverse.zig b/test/behavior/bitreverse.zig index 11179b964a..a355572f84 100644 --- a/test/behavior/bitreverse.zig +++ b/test/behavior/bitreverse.zig @@ -6,7 +6,6 @@ const minInt = std.math.minInt; test "@bitReverse large exotic integer" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // Currently failing on stage1 for big-endian targets if (builtin.zig_backend == .stage1) return error.SkipZigTest; diff --git a/test/behavior/bugs/1381.zig b/test/behavior/bugs/1381.zig index 2f05d2fa96..fb46869e99 100644 --- a/test/behavior/bugs/1381.zig +++ b/test/behavior/bugs/1381.zig @@ -14,7 +14,6 @@ const A = union(enum) { test "union that needs padding bytes inside an array" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var as = [_]A{ A{ .B = B{ .D = 1 } }, A{ .B = B{ .D = 1 } }, diff --git a/test/behavior/bugs/1735.zig b/test/behavior/bugs/1735.zig index 556b899de1..d2ab25624f 100644 --- a/test/behavior/bugs/1735.zig +++ b/test/behavior/bugs/1735.zig @@ -45,7 +45,6 @@ test "initialization" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var t = a.init(); try std.testing.expect(t.foo.len == 0); } diff --git a/test/behavior/bugs/4954.zig b/test/behavior/bugs/4954.zig index eaae4d8ba2..737333a3d7 100644 --- a/test/behavior/bugs/4954.zig +++ b/test/behavior/bugs/4954.zig @@ -5,7 +5,6 @@ fn f(buf: []u8) void { } test "crash" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 4ce4faa375..d3b9979086 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -223,7 +223,7 @@ test "@intToEnum passed a comptime_int to an enum with one item" { } test "@intCast to u0 and use the result" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest(zero: u1, one: u1, bigzero: i32) !void { @@ -324,7 +324,6 @@ test "cast from ?[*]T to ??[*]T" { test "peer type unsigned int to signed" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var w: u31 = 5; var x: u8 = 7; @@ -401,7 +400,6 @@ test "implicitly cast from [0]T to anyerror![]T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO try testCastZeroArrayToErrSliceMut(); comptime try testCastZeroArrayToErrSliceMut(); @@ -419,7 +417,6 @@ test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() anyerror!void { @@ -475,7 +472,6 @@ fn testCastConstArrayRefToConstSlice() !void { test "peer type resolution: error and [N]T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK")); comptime try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK")); @@ -646,7 +642,6 @@ test "peer cast *[0]T to []const T" { test "peer cast *[N]T to [*]T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var array = [4:99]i32{ 1, 2, 3, 4 }; var dest: [*]i32 = undefined; @@ -700,7 +695,6 @@ test "peer cast [N:x]T to [N]T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -717,7 +711,6 @@ test "peer cast *[N:x]T to *[N]T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -771,7 +764,6 @@ test "peer type resolution implicit cast to return type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -886,7 +878,6 @@ test "pointer reinterpret const float to int" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO // The hex representation is 0x3fe3333333333303. const float: f64 = 5.99999999999994648725e-01; @@ -972,7 +963,6 @@ test "peer type resolution: [0]u8 and []const u8" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); @@ -1060,7 +1050,6 @@ test "implicit cast *[0]T to E![]const u8" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var x = @as(anyerror![]const u8, &[0]u8{}); try expect((x catch unreachable).len == 0); @@ -1068,14 +1057,11 @@ test "implicit cast *[0]T to E![]const u8" { var global_array: [4]u8 = undefined; test "cast from array reference to fn: comptime fn ptr" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - const f = @ptrCast(*const fn () callconv(.C) void, &global_array); try expect(@ptrToInt(f) == @ptrToInt(&global_array)); } test "cast from array reference to fn: runtime fn ptr" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var f = @ptrCast(*const fn () callconv(.C) void, &global_array); try expect(@ptrToInt(f) == @ptrToInt(&global_array)); @@ -1099,8 +1085,6 @@ test "*const [N]null u8 to ?[]const u8" { } test "cast between [*c]T and ?[*:0]T on fn parameter" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - const S = struct { const Handler = ?fn ([*c]const u8) callconv(.C) void; fn addCallback(handler: Handler) void { @@ -1132,7 +1116,6 @@ test "assignment to optional pointer result loc" { test "cast between *[N]void and []void" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var a: [4]void = undefined; var b: []void = &a; @@ -1142,7 +1125,6 @@ test "cast between *[N]void and []void" { test "peer resolve arrays of different size to const slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO try expect(mem.eql(u8, boolToStr(true), "true")); try expect(mem.eql(u8, boolToStr(false), "false")); @@ -1213,7 +1195,6 @@ test "peer type resolution: unreachable, null, slice" { test "cast i8 fn call peers to i32 result" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { diff --git a/test/behavior/defer.zig b/test/behavior/defer.zig index 236b37a51c..5f41af8f56 100644 --- a/test/behavior/defer.zig +++ b/test/behavior/defer.zig @@ -95,7 +95,6 @@ fn runSomeErrorDefers(x: bool) !bool { } test "mixing normal and error defers" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 8b56503ec3..d47ec50f5d 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -616,7 +616,6 @@ fn testEnumWithSpecifiedTagValues(x: MultipleChoice) !void { } test "enum with specified tag values" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; @@ -625,7 +624,6 @@ test "enum with specified tag values" { } test "non-exhaustive enum" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; @@ -691,7 +689,6 @@ test "empty non-exhaustive enum" { } test "single field non-exhaustive enum" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; @@ -760,7 +757,6 @@ test "cast integer literal to enum" { } test "enum with specified and unspecified tag values" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; @@ -942,7 +938,6 @@ test "enum value allocation" { } test "enum literal casting to tagged union" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; @@ -968,7 +963,6 @@ test "enum literal casting to tagged union" { const Bar = enum { A, B, C, D }; test "enum literal casting to error union with payload enum" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index 71602aa698..b3a32fe9d9 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -216,7 +216,6 @@ fn addPointCoords(pt: Point) i32 { } test "pass by non-copying value through var arg" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; diff --git a/test/behavior/if.zig b/test/behavior/if.zig index cf7a932ccb..d8beba0222 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -48,7 +48,6 @@ var global_with_val: anyerror!u32 = 0; var global_with_err: anyerror!u32 = error.SomeError; test "unwrap mutable global var" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; diff --git a/test/behavior/ir_block_deps.zig b/test/behavior/ir_block_deps.zig index d7d50b4be1..359e01aa69 100644 --- a/test/behavior/ir_block_deps.zig +++ b/test/behavior/ir_block_deps.zig @@ -20,7 +20,6 @@ fn getErrInt() anyerror!i32 { test "ir block deps" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO try expect((foo(1) catch unreachable) == 0); try expect((foo(2) catch unreachable) == 0); diff --git a/test/behavior/namespace_depends_on_compile_var.zig b/test/behavior/namespace_depends_on_compile_var.zig index db1dfaf308..bfc6682f12 100644 --- a/test/behavior/namespace_depends_on_compile_var.zig +++ b/test/behavior/namespace_depends_on_compile_var.zig @@ -4,7 +4,6 @@ const expect = std.testing.expect; test "namespace depends on compile var" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (some_namespace.a_bool) { try expect(some_namespace.a_bool); } else { diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index fdef0cfa96..cc8174dc13 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -28,7 +28,6 @@ pub const EmptyStruct = struct {}; test "optional pointer to size zero struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var e = EmptyStruct{}; var o: ?*EmptyStruct = &e; @@ -37,7 +36,6 @@ test "optional pointer to size zero struct" { test "equality compare optional pointers" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO try testNullPtrsEql(); comptime try testNullPtrsEql(); @@ -152,7 +150,6 @@ fn test_cmp_optional_non_optional() !void { test "unwrap function call with optional pointer return value" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { fn entry() !void { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 47a71ae68e..f175f1823f 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -247,7 +247,6 @@ test "usingnamespace within struct scope" { test "struct field init with catch" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { diff --git a/test/behavior/try.zig b/test/behavior/try.zig index 898c596ade..f2a836e182 100644 --- a/test/behavior/try.zig +++ b/test/behavior/try.zig @@ -3,7 +3,6 @@ const builtin = @import("builtin"); const expect = std.testing.expect; test "try on error union" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; diff --git a/test/behavior/underscore.zig b/test/behavior/underscore.zig index c15f8105aa..9305149f5a 100644 --- a/test/behavior/underscore.zig +++ b/test/behavior/underscore.zig @@ -7,7 +7,6 @@ test "ignore lval with underscore" { } test "ignore lval with underscore (while loop)" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; diff --git a/test/behavior/while.zig b/test/behavior/while.zig index 03670d28a7..c1f41e5677 100644 --- a/test/behavior/while.zig +++ b/test/behavior/while.zig @@ -175,7 +175,6 @@ test "while with optional as condition with else" { } test "while with error union condition" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; @@ -248,7 +247,6 @@ fn returnTrue() bool { } test "return with implicit cast from while loop" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; returnWithImplicitCastFromWhileLoopTest() catch unreachable; @@ -260,7 +258,6 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { } test "while on error union with else result follow else prong" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; @@ -271,7 +268,6 @@ test "while on error union with else result follow else prong" { } test "while on error union with else result follow break prong" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; -- cgit v1.2.3 From 157f66ec077ad02f08891bec1a426c0ffef98e09 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 28 Feb 2022 19:22:16 -0700 Subject: Sema: fix pointer type hash and equality functions Several issues with pointer types are fixed: Prior to this commit, Zig would not canonicalize a pointer type with an explicit alignment to alignment=0 if it matched the pointee ABI alignment. In order to fix this, `Type.ptr` now takes a Target parameter. I also moved the host_size canonicalization to `Type.ptr` since target is now available. Similarly, is_allowzero in the case of C pointers is now treated as a canonicalization done by the function rather than a precondition. in-memory coercion for pointers now properly checks ABI alignment of pointee types instead of incorrectly treating the 0 value as an alignment. Type equality is completely reworked based on the tag() rather than the zigTypeTag(). It's still semantically based on zigTypeTag() but that knowledge is implied rather than dictating the control flow of the logic. Importantly, this fixes cases for opaques, structs, tuples, enums, and unions, where type equality was incorrectly returning based on whether the tag() values were equal. Additionally, pointer type equality now takes into account alignment. Because we canonicalize non-zero alignment which equals pointee type ABI alignment to alignment=0, this now can be a simple integer comparison. Type hashing is implemented for pointers and floats. Array types now additionally hash their sentinels. This regressed some behavior tests that were passing but only because of bugs regarding type equality. The C backend has a noticeable problem with lowering differently-aligned pointers (particularly slices) as the same type, causing C compilation errors due to duplicate declarations. --- src/Sema.zig | 203 +++++++++++------- src/codegen.zig | 2 +- src/type.zig | 535 ++++++++++++++++++++++++++++++---------------- test/behavior/align.zig | 14 +- test/behavior/array.zig | 1 + test/behavior/ptrcast.zig | 2 + test/behavior/union.zig | 2 - 7 files changed, 492 insertions(+), 267 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/Sema.zig b/src/Sema.zig index 56cc3b13bb..6ef4798da6 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1555,7 +1555,8 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE const bin_inst = sema.code.instructions.items(.data)[inst].bin; const pointee_ty = try sema.resolveType(block, src, bin_inst.lhs); const ptr = sema.resolveInst(bin_inst.rhs); - const addr_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local); + const target = sema.mod.getTarget(); + const addr_space = target_util.defaultAddressSpace(target, .local); if (Air.refToIndex(ptr)) |ptr_inst| { if (sema.air_instructions.items(.tag)[ptr_inst] == .constant) { @@ -1575,7 +1576,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE try inferred_alloc.stored_inst_list.append(sema.arena, operand); try sema.requireRuntimeBlock(block, src); - const ptr_ty = try Type.ptr(sema.arena, .{ + const ptr_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = pointee_ty, .@"align" = inferred_alloc.alignment, .@"addrspace" = addr_space, @@ -1593,7 +1594,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE try pointee_ty.copy(anon_decl.arena()), Value.undef, ); - const ptr_ty = try Type.ptr(sema.arena, .{ + const ptr_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = pointee_ty, .@"align" = iac.data.alignment, .@"addrspace" = addr_space, @@ -1642,7 +1643,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE } } - const ptr_ty = try Type.ptr(sema.arena, .{ + const ptr_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = pointee_ty, .@"addrspace" = addr_space, }); @@ -1663,7 +1664,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE } const ty_op = air_datas[trash_inst].ty_op; const operand_ty = sema.getTmpAir().typeOf(ty_op.operand); - const ptr_operand_ty = try Type.ptr(sema.arena, .{ + const ptr_operand_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = operand_ty, .@"addrspace" = addr_space, }); @@ -2225,9 +2226,10 @@ fn zirRetPtr( return sema.analyzeComptimeAlloc(block, fn_ret_ty, 0, src); } - const ptr_type = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const ptr_type = try Type.ptr(sema.arena, target, .{ .pointee_type = sema.fn_ret_ty, - .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + .@"addrspace" = target_util.defaultAddressSpace(target, .local), }); if (block.inlining != null) { @@ -2389,10 +2391,11 @@ fn zirAllocExtended( if (!small.is_const) { try sema.validateVarType(block, ty_src, var_ty, false); } - const ptr_type = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const ptr_type = try Type.ptr(sema.arena, target, .{ .pointee_type = var_ty, .@"align" = alignment, - .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + .@"addrspace" = target_util.defaultAddressSpace(target, .local), }); try sema.requireRuntimeBlock(block, src); try sema.resolveTypeLayout(block, src, var_ty); @@ -2450,9 +2453,10 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I if (block.is_comptime) { return sema.analyzeComptimeAlloc(block, var_ty, 0, ty_src); } - const ptr_type = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const ptr_type = try Type.ptr(sema.arena, target, .{ .pointee_type = var_ty, - .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + .@"addrspace" = target_util.defaultAddressSpace(target, .local), }); try sema.requireRuntimeBlock(block, var_decl_src); try sema.resolveTypeLayout(block, ty_src, var_ty); @@ -2471,9 +2475,10 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai return sema.analyzeComptimeAlloc(block, var_ty, 0, ty_src); } try sema.validateVarType(block, ty_src, var_ty, false); - const ptr_type = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const ptr_type = try Type.ptr(sema.arena, target, .{ .pointee_type = var_ty, - .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + .@"addrspace" = target_util.defaultAddressSpace(target, .local), }); try sema.requireRuntimeBlock(block, var_decl_src); try sema.resolveTypeLayout(block, ty_src, var_ty); @@ -2542,7 +2547,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com try sema.mod.declareDeclDependency(sema.owner_decl, decl); const final_elem_ty = try decl.ty.copy(sema.arena); - const final_ptr_ty = try Type.ptr(sema.arena, .{ + const final_ptr_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = final_elem_ty, .mutable = var_is_mut, .@"align" = iac.data.alignment, @@ -2565,7 +2570,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com const peer_inst_list = inferred_alloc.data.stored_inst_list.items; const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, .none); - const final_ptr_ty = try Type.ptr(sema.arena, .{ + const final_ptr_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = final_elem_ty, .mutable = var_is_mut, .@"align" = inferred_alloc.data.alignment, @@ -3335,10 +3340,11 @@ fn storeToInferredAlloc( // for the inferred allocation. try inferred_alloc.data.stored_inst_list.append(sema.arena, operand); // Create a runtime bitcast instruction with exactly the type the pointer wants. - const ptr_ty = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const ptr_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = operand_ty, .@"align" = inferred_alloc.data.alignment, - .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + .@"addrspace" = target_util.defaultAddressSpace(target, .local), }); const bitcasted_ptr = try block.addBitCast(ptr_ty, ptr); return sema.storePtr(block, src, bitcasted_ptr, operand); @@ -5444,7 +5450,8 @@ fn analyzeOptionalPayloadPtr( } const child_type = try opt_type.optionalChildAlloc(sema.arena); - const child_pointer = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const child_pointer = try Type.ptr(sema.arena, target, .{ .pointee_type = child_type, .mutable = !optional_ptr_ty.isConstPtr(), .@"addrspace" = optional_ptr_ty.ptrAddressSpace(), @@ -5509,7 +5516,8 @@ fn zirOptionalPayload( return sema.failWithExpectedOptionalType(block, src, operand_ty); } const ptr_info = operand_ty.ptrInfo().data; - break :t try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + break :t try Type.ptr(sema.arena, target, .{ .pointee_type = try ptr_info.pointee_type.copy(sema.arena), .@"align" = ptr_info.@"align", .@"addrspace" = ptr_info.@"addrspace", @@ -5607,7 +5615,8 @@ fn analyzeErrUnionPayloadPtr( return sema.fail(block, src, "expected error union type, found {}", .{operand_ty.elemType()}); const payload_ty = operand_ty.elemType().errorUnionPayload(); - const operand_pointer_ty = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const operand_pointer_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = payload_ty, .mutable = !operand_ty.isConstPtr(), .@"addrspace" = operand_ty.ptrAddressSpace(), @@ -6517,7 +6526,8 @@ fn zirSwitchCapture( if (is_ref) { assert(operand_is_ref); - const field_ty_ptr = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const field_ty_ptr = try Type.ptr(sema.arena, target, .{ .pointee_type = field.ty, .@"addrspace" = .generic, .mutable = operand_ptr_ty.ptrIsMutable(), @@ -11327,7 +11337,8 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple; const elem_type = try sema.resolveType(block, .unneeded, inst_data.elem_type); - const ty = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const ty = try Type.ptr(sema.arena, target, .{ .pointee_type = elem_type, .@"addrspace" = .generic, .mutable = inst_data.is_mutable, @@ -11343,6 +11354,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air defer tracy.end(); const src: LazySrcLoc = .unneeded; + const elem_ty_src: LazySrcLoc = .unneeded; const inst_data = sema.code.instructions.items(.data)[inst].ptr_type; const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index); @@ -11366,41 +11378,40 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air break :blk try sema.analyzeAddrspace(block, .unneeded, ref, .pointer); } else .generic; - const bit_start = if (inst_data.flags.has_bit_range) blk: { + const bit_offset = if (inst_data.flags.has_bit_range) blk: { const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); extra_i += 1; break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16); } else 0; - var host_size: u16 = if (inst_data.flags.has_bit_range) blk: { + const host_size: u16 = if (inst_data.flags.has_bit_range) blk: { const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); extra_i += 1; break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16); } else 0; - const elem_type = try sema.resolveType(block, .unneeded, extra.data.elem_type); - - if (host_size != 0) { - if (bit_start >= host_size * 8) { - return sema.fail(block, src, "bit offset starts after end of host integer", .{}); - } - const target = sema.mod.getTarget(); - const elem_type_bits = elem_type.bitSize(target); - if (host_size * 8 == elem_type_bits) { - assert(bit_start == 0); - host_size = 0; - } + if (host_size != 0 and bit_offset >= host_size * 8) { + return sema.fail(block, src, "bit offset starts after end of host integer", .{}); } - const ty = try Type.ptr(sema.arena, .{ - .pointee_type = elem_type, + const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type); + const elem_ty = if (abi_align == 0) + unresolved_elem_ty + else t: { + const elem_ty = try sema.resolveTypeFields(block, elem_ty_src, unresolved_elem_ty); + try sema.resolveTypeLayout(block, elem_ty_src, elem_ty); + break :t elem_ty; + }; + const target = sema.mod.getTarget(); + const ty = try Type.ptr(sema.arena, target, .{ + .pointee_type = elem_ty, .sentinel = sentinel, .@"align" = abi_align, .@"addrspace" = address_space, - .bit_offset = bit_start, + .bit_offset = bit_offset, .host_size = host_size, .mutable = inst_data.flags.is_mutable, - .@"allowzero" = inst_data.flags.is_allowzero or inst_data.size == .C, + .@"allowzero" = inst_data.flags.is_allowzero, .@"volatile" = inst_data.flags.is_volatile, .size = inst_data.size, }); @@ -11721,15 +11732,16 @@ fn zirArrayInit( try sema.resolveTypeLayout(block, src, elem_ty); if (is_ref) { - const alloc_ty = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const alloc_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = array_ty, - .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + .@"addrspace" = target_util.defaultAddressSpace(target, .local), }); const alloc = try block.addTy(.alloc, alloc_ty); - const elem_ptr_ty = try Type.ptr(sema.arena, .{ + const elem_ptr_ty = try Type.ptr(sema.arena, target, .{ .mutable = true, - .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + .@"addrspace" = target_util.defaultAddressSpace(target, .local), .pointee_type = elem_ty, }); const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty); @@ -11788,12 +11800,13 @@ fn zirArrayInitAnon( try sema.requireRuntimeBlock(block, runtime_src); if (is_ref) { + const target = sema.mod.getTarget(); const alloc = try block.addTy(.alloc, tuple_ty); for (operands) |operand, i_usize| { const i = @intCast(u32, i_usize); - const field_ptr_ty = try Type.ptr(sema.arena, .{ + const field_ptr_ty = try Type.ptr(sema.arena, target, .{ .mutable = true, - .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + .@"addrspace" = target_util.defaultAddressSpace(target, .local), .pointee_type = types[i], }); const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty); @@ -12068,6 +12081,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I const union_val = val.cast(Value.Payload.Union).?.data; const tag_ty = type_info_ty.unionTagType().?; const tag_index = tag_ty.enumTagFieldIndex(union_val.tag).?; + const target = sema.mod.getTarget(); switch (@intToEnum(std.builtin.TypeId, tag_index)) { .Type => return Air.Inst.Ref.type_type, .Void => return Air.Inst.Ref.void_type, @@ -12146,11 +12160,14 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{}); } const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data; - const ptr_ty = try Type.ptr(sema.arena, .{ .@"addrspace" = .generic, .pointee_type = child_ty }); + const ptr_ty = try Type.ptr(sema.arena, target, .{ + .@"addrspace" = .generic, + .pointee_type = child_ty, + }); actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?; } - const ty = try Type.ptr(sema.arena, .{ + const ty = try Type.ptr(sema.arena, target, .{ .size = ptr_size, .mutable = !is_const_val.toBool(), .@"volatile" = is_volatile_val.toBool(), @@ -12176,7 +12193,10 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I var buffer: Value.ToTypeBuffer = undefined; const child_ty = try child_val.toType(&buffer).copy(sema.arena); const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: { - const ptr_ty = try Type.ptr(sema.arena, .{ .@"addrspace" = .generic, .pointee_type = child_ty }); + const ptr_ty = try Type.ptr(sema.arena, target, .{ + .@"addrspace" = .generic, + .pointee_type = child_ty, + }); break :blk (try sema.pointerDeref(block, src, p.data, ptr_ty)).?; } else null; @@ -12468,7 +12488,8 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A // TODO insert safety check that the alignment is correct const ptr_info = ptr_ty.ptrInfo().data; - const dest_ty = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const dest_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = ptr_info.pointee_type, .@"align" = dest_align, .@"addrspace" = ptr_info.@"addrspace", @@ -13408,11 +13429,12 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr ptr_ty_data.@"align" = @intCast(u32, field.abi_align.toUnsignedInt()); } - const actual_field_ptr_ty = try Type.ptr(sema.arena, ptr_ty_data); + const target = sema.mod.getTarget(); + const actual_field_ptr_ty = try Type.ptr(sema.arena, target, ptr_ty_data); const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src); ptr_ty_data.pointee_type = struct_ty; - const result_ptr = try Type.ptr(sema.arena, ptr_ty_data); + const result_ptr = try Type.ptr(sema.arena, target, ptr_ty_data); if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| { const payload = field_ptr_val.castTag(.field_ptr).?.data; @@ -13509,7 +13531,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void const uncasted_src_ptr_ty = sema.typeOf(uncasted_src_ptr); try sema.checkPtrOperand(block, src_src, uncasted_src_ptr_ty); const src_ptr_info = uncasted_src_ptr_ty.ptrInfo().data; - const wanted_src_ptr_ty = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const wanted_src_ptr_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = dest_ptr_ty.elemType2(), .@"align" = src_ptr_info.@"align", .@"addrspace" = src_ptr_info.@"addrspace", @@ -14149,9 +14172,10 @@ fn panicWithMsg( const panic_fn = try sema.getBuiltin(block, src, "panic"); const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace"); const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty); - const ptr_stack_trace_ty = try Type.ptr(arena, .{ + const target = mod.getTarget(); + const ptr_stack_trace_ty = try Type.ptr(arena, target, .{ .pointee_type = stack_trace_ty, - .@"addrspace" = target_util.defaultAddressSpace(mod.getTarget(), .global_constant), // TODO might need a place that is more dynamic + .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic }); const null_stack_trace = try sema.addConstant( try Type.optional(arena, ptr_stack_trace_ty), @@ -14405,6 +14429,8 @@ fn fieldPtr( else object_ty; + const target = sema.mod.getTarget(); + switch (inner_ty.zigTypeTag()) { .Array => { if (mem.eql(u8, field_name, "len")) { @@ -14444,7 +14470,7 @@ fn fieldPtr( } try sema.requireRuntimeBlock(block, src); - const result_ty = try Type.ptr(sema.arena, .{ + const result_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = slice_ptr_ty, .mutable = object_ptr_ty.ptrIsMutable(), .@"addrspace" = object_ptr_ty.ptrAddressSpace(), @@ -14463,7 +14489,7 @@ fn fieldPtr( } try sema.requireRuntimeBlock(block, src); - const result_ty = try Type.ptr(sema.arena, .{ + const result_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = Type.usize, .mutable = object_ptr_ty.ptrIsMutable(), .@"addrspace" = object_ptr_ty.ptrAddressSpace(), @@ -14692,7 +14718,8 @@ fn finishFieldCallBind( object_ptr: Air.Inst.Ref, ) CompileError!Air.Inst.Ref { const arena = sema.arena; - const ptr_field_ty = try Type.ptr(arena, .{ + const target = sema.mod.getTarget(); + const ptr_field_ty = try Type.ptr(arena, target, .{ .pointee_type = field_ty, .mutable = ptr_ty.ptrIsMutable(), .@"addrspace" = ptr_ty.ptrAddressSpace(), @@ -14831,7 +14858,8 @@ fn structFieldPtrByIndex( } } - const ptr_field_ty = try Type.ptr(sema.arena, ptr_ty_data); + const target = sema.mod.getTarget(); + const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data); if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| { return sema.addConstant( @@ -14959,7 +14987,8 @@ fn unionFieldPtr( const field_index = @intCast(u32, field_index_big); const field = union_obj.fields.values()[field_index]; - const ptr_field_ty = try Type.ptr(arena, .{ + const target = sema.mod.getTarget(); + const ptr_field_ty = try Type.ptr(arena, target, .{ .pointee_type = field.ty, .mutable = union_ptr_ty.ptrIsMutable(), .@"addrspace" = union_ptr_ty.ptrAddressSpace(), @@ -15033,7 +15062,8 @@ fn elemPtr( .Pointer => { // In all below cases, we have to deref the ptr operand to get the actual array pointer. const array = try sema.analyzeLoad(block, array_ptr_src, array_ptr, array_ptr_src); - const result_ty = try array_ty.elemPtrType(sema.arena); + const target = sema.mod.getTarget(); + const result_ty = try array_ty.elemPtrType(sema.arena, target); switch (array_ty.ptrSize()) { .Slice => { const maybe_slice_val = try sema.resolveDefinedValue(block, array_ptr_src, array); @@ -15172,7 +15202,8 @@ fn tupleFieldPtr( } const field_ty = tuple_info.types[field_index]; - const ptr_field_ty = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const ptr_field_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = field_ty, .mutable = tuple_ptr_ty.ptrIsMutable(), .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(), @@ -15264,7 +15295,8 @@ fn elemPtrArray( elem_index_src: LazySrcLoc, ) CompileError!Air.Inst.Ref { const array_ptr_ty = sema.typeOf(array_ptr); - const result_ty = try array_ptr_ty.elemPtrType(sema.arena); + const target = sema.mod.getTarget(); + const result_ty = try array_ptr_ty.elemPtrType(sema.arena, target); if (try sema.resolveDefinedValue(block, src, array_ptr)) |array_ptr_val| { if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| { @@ -15957,15 +15989,28 @@ fn coerceInMemoryAllowedPtrs( // In this case, if they share the same child type, no need to resolve // pointee type alignment. Otherwise both pointee types must have their alignment // resolved and we compare the alignment numerically. - if (src_info.@"align" != 0 or dest_info.@"align" != 0 or - !dest_info.pointee_type.eql(src_info.pointee_type)) - { - const src_align = src_info.@"align"; - const dest_align = dest_info.@"align"; + alignment: { + if (src_info.@"align" == 0 and dest_info.@"align" == 0 and + dest_info.pointee_type.eql(src_info.pointee_type)) + { + break :alignment; + } + + const src_align = if (src_info.@"align" != 0) + src_info.@"align" + else + src_info.pointee_type.abiAlignment(target); + + const dest_align = if (dest_info.@"align" != 0) + dest_info.@"align" + else + dest_info.pointee_type.abiAlignment(target); if (dest_align > src_align) { return .no_match; } + + break :alignment; } return .ok; @@ -16874,6 +16919,7 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { try sema.mod.declareDeclDependency(sema.owner_decl, decl); try sema.ensureDeclAnalyzed(decl); + const target = sema.mod.getTarget(); const decl_tv = try decl.typedValue(); if (decl_tv.val.castTag(.variable)) |payload| { const variable = payload.data; @@ -16881,7 +16927,7 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { 0 else @intCast(u32, decl.align_val.toUnsignedInt()); - const ty = try Type.ptr(sema.arena, .{ + const ty = try Type.ptr(sema.arena, target, .{ .pointee_type = decl_tv.ty, .mutable = variable.is_mutable, .@"addrspace" = decl.@"addrspace", @@ -16890,7 +16936,7 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { return sema.addConstant(ty, try Value.Tag.decl_ref.create(sema.arena, decl)); } return sema.addConstant( - try Type.ptr(sema.arena, .{ + try Type.ptr(sema.arena, target, .{ .pointee_type = decl_tv.ty, .mutable = false, .@"addrspace" = decl.@"addrspace", @@ -16918,12 +16964,13 @@ fn analyzeRef( try sema.requireRuntimeBlock(block, src); const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local); - const ptr_type = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const ptr_type = try Type.ptr(sema.arena, target, .{ .pointee_type = operand_ty, .mutable = false, .@"addrspace" = address_space, }); - const mut_ptr_type = try Type.ptr(sema.arena, .{ + const mut_ptr_type = try Type.ptr(sema.arena, target, .{ .pointee_type = operand_ty, .@"addrspace" = address_space, }); @@ -17174,11 +17221,12 @@ fn analyzeSlice( const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo().data; const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize() != .C; + const target = sema.mod.getTarget(); if (opt_new_len_val) |new_len_val| { const new_len_int = new_len_val.toUnsignedInt(); - const return_ty = try Type.ptr(sema.arena, .{ + const return_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty), .sentinel = null, .@"align" = new_ptr_ty_info.@"align", @@ -17206,7 +17254,7 @@ fn analyzeSlice( return sema.fail(block, ptr_src, "non-zero length slice of undefined pointer", .{}); } - const return_ty = try Type.ptr(sema.arena, .{ + const return_ty = try Type.ptr(sema.arena, target, .{ .pointee_type = elem_ty, .sentinel = sentinel, .@"align" = new_ptr_ty_info.@"align", @@ -17904,14 +17952,14 @@ fn resolvePeerTypes( else => unreachable, }; - return Type.ptr(sema.arena, info.data); + return Type.ptr(sema.arena, target, info.data); } if (make_the_slice_const) { // turn []T => []const T var info = chosen_ty.ptrInfo(); info.data.mutable = false; - return Type.ptr(sema.arena, info.data); + return Type.ptr(sema.arena, target, info.data); } return chosen_ty; @@ -19121,7 +19169,8 @@ fn analyzeComptimeAlloc( // Needed to make an anon decl with type `var_type` (the `finish()` call below). _ = try sema.typeHasOnePossibleValue(block, src, var_type); - const ptr_type = try Type.ptr(sema.arena, .{ + const target = sema.mod.getTarget(); + const ptr_type = try Type.ptr(sema.arena, target, .{ .pointee_type = var_type, .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant), .@"align" = alignment, diff --git a/src/codegen.zig b/src/codegen.zig index 2484cb0e59..67119bf9fa 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -657,7 +657,7 @@ fn lowerDeclRef( .data = typed_value.val.sliceLen(), }; switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ - .ty = Type.initTag(.usize), + .ty = Type.usize, .val = Value.initPayload(&slice_len.base), }, code, debug_output)) { .appended => {}, diff --git a/src/type.zig b/src/type.zig index fb3ab5d28f..1c8e1bfa50 100644 --- a/src/type.zig +++ b/src/type.zig @@ -491,94 +491,115 @@ pub const Type = extern union { pub fn eql(a: Type, b: Type) bool { // As a shortcut, if the small tags / addresses match, we're done. - if (a.tag_if_small_enough == b.tag_if_small_enough) - return true; - const zig_tag_a = a.zigTypeTag(); - const zig_tag_b = b.zigTypeTag(); - if (zig_tag_a != zig_tag_b) - return false; - switch (zig_tag_a) { - .EnumLiteral => return true, - .Type => return true, - .Void => return true, - .Bool => return true, - .NoReturn => return true, - .ComptimeFloat => return true, - .ComptimeInt => return true, - .Undefined => return true, - .Null => return true, - .AnyFrame => { - return a.elemType().eql(b.elemType()); - }, - .Pointer => { - const info_a = a.ptrInfo().data; - const info_b = b.ptrInfo().data; - if (!info_a.pointee_type.eql(info_b.pointee_type)) - return false; - if (info_a.size != info_b.size) - return false; - if (info_a.mutable != info_b.mutable) - return false; - if (info_a.@"volatile" != info_b.@"volatile") - return false; - if (info_a.@"allowzero" != info_b.@"allowzero") - return false; - if (info_a.bit_offset != info_b.bit_offset) - return false; - if (info_a.host_size != info_b.host_size) - return false; - if (info_a.@"addrspace" != info_b.@"addrspace") - return false; + if (a.tag_if_small_enough == b.tag_if_small_enough) return true; - const sentinel_a = info_a.sentinel; - const sentinel_b = info_b.sentinel; - if (sentinel_a) |sa| { - if (sentinel_b) |sb| { - if (!sa.eql(sb, info_a.pointee_type)) - return false; - } else { - return false; - } - } else { - if (sentinel_b != null) - return false; - } + switch (a.tag()) { + .generic_poison => unreachable, - return true; + // Detect that e.g. u64 != usize, even if the bits match on a particular target. + .usize, + .isize, + .c_short, + .c_ushort, + .c_int, + .c_uint, + .c_long, + .c_ulong, + .c_longlong, + .c_ulonglong, + + .f16, + .f32, + .f64, + .f80, + .f128, + .c_longdouble, + + .bool, + .void, + .type, + .comptime_int, + .comptime_float, + .noreturn, + .@"null", + .@"undefined", + .@"anyopaque", + .@"anyframe", + .enum_literal, + => |a_tag| { + assert(a_tag != b.tag()); // because of the comparison at the top of the function. + return false; }, - .Int => { - // Detect that e.g. u64 != usize, even if the bits match on a particular target. - const a_is_named_int = a.isNamedInt(); - const b_is_named_int = b.isNamedInt(); - if (a_is_named_int != b_is_named_int) - return false; - if (a_is_named_int) - return a.tag() == b.tag(); - // Remaining cases are arbitrary sized integers. - // The target will not be branched upon, because we handled target-dependent cases above. + + .u1, + .u8, + .i8, + .u16, + .i16, + .u32, + .i32, + .u64, + .i64, + .u128, + .i128, + .int_signed, + .int_unsigned, + => { + if (b.zigTypeTag() != .Int) return false; + if (b.isNamedInt()) return false; + + // Arbitrary sized integers. The target will not be branched upon, + // because we handled target-dependent cases above. const info_a = a.intInfo(@as(Target, undefined)); const info_b = b.intInfo(@as(Target, undefined)); return info_a.signedness == info_b.signedness and info_a.bits == info_b.bits; }, - .Array, .Vector => { - if (a.arrayLen() != b.arrayLen()) - return false; - const elem_ty = a.elemType(); - if (!elem_ty.eql(b.elemType())) - return false; - const sentinel_a = a.sentinel(); - const sentinel_b = b.sentinel(); - if (sentinel_a) |sa| { - if (sentinel_b) |sb| { - return sa.eql(sb, elem_ty); - } else { - return false; - } - } else { - return sentinel_b == null; + + .error_set, + .error_set_single, + .anyerror, + .error_set_inferred, + .error_set_merged, + => { + if (b.zigTypeTag() != .ErrorSet) return false; + + // TODO: revisit the language specification for how to evaluate equality + // for error set types. + + if (a.tag() == .anyerror and b.tag() == .anyerror) { + return true; + } + + if (a.tag() == .error_set and b.tag() == .error_set) { + return a.castTag(.error_set).?.data.owner_decl == b.castTag(.error_set).?.data.owner_decl; } + + if (a.tag() == .error_set_inferred and b.tag() == .error_set_inferred) { + return a.castTag(.error_set_inferred).?.data == b.castTag(.error_set_inferred).?.data; + } + + if (a.tag() == .error_set_single and b.tag() == .error_set_single) { + const a_data = a.castTag(.error_set_single).?.data; + const b_data = b.castTag(.error_set_single).?.data; + return std.mem.eql(u8, a_data, b_data); + } + return false; }, - .Fn => { + + .@"opaque" => { + const opaque_obj_a = a.castTag(.@"opaque").?.data; + const opaque_obj_b = (b.castTag(.@"opaque") orelse return false).data; + return opaque_obj_a == opaque_obj_b; + }, + + .fn_noreturn_no_args, + .fn_void_no_args, + .fn_naked_noreturn_no_args, + .fn_ccc_void_no_args, + .function, + => { + if (b.zigTypeTag() != .Fn) return false; + const a_info = a.fnInfo(); const b_info = b.fnInfo(); @@ -613,76 +634,105 @@ pub const Type = extern union { return true; }, - .Optional => { - var buf_a: Payload.ElemType = undefined; - var buf_b: Payload.ElemType = undefined; - return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b)); - }, - .Struct => { - if (a.castTag(.@"struct")) |a_payload| { - if (b.castTag(.@"struct")) |b_payload| { - return a_payload.data == b_payload.data; - } - } - if (a.castTag(.tuple)) |a_payload| { - if (b.castTag(.tuple)) |b_payload| { - if (a_payload.data.types.len != b_payload.data.types.len) return false; - - for (a_payload.data.types) |a_ty, i| { - const b_ty = b_payload.data.types[i]; - if (!eql(a_ty, b_ty)) return false; - } - for (a_payload.data.values) |a_val, i| { - const ty = a_payload.data.types[i]; - const b_val = b_payload.data.values[i]; - if (a_val.tag() == .unreachable_value) { - if (b_val.tag() == .unreachable_value) { - continue; - } else { - return false; - } - } else { - if (b_val.tag() == .unreachable_value) { - return false; - } else { - if (!Value.eql(a_val, b_val, ty)) return false; - } - } - } + .array, + .array_u8_sentinel_0, + .array_u8, + .array_sentinel, + .vector, + => { + if (a.zigTypeTag() != b.zigTypeTag()) return false; - return true; + if (a.arrayLen() != b.arrayLen()) + return false; + const elem_ty = a.elemType(); + if (!elem_ty.eql(b.elemType())) + return false; + const sentinel_a = a.sentinel(); + const sentinel_b = b.sentinel(); + if (sentinel_a) |sa| { + if (sentinel_b) |sb| { + return sa.eql(sb, elem_ty); + } else { + return false; } + } else { + return sentinel_b == null; } - return a.tag() == b.tag(); }, - .Enum => { - if (a.cast(Payload.EnumFull)) |a_payload| { - if (b.cast(Payload.EnumFull)) |b_payload| { - return a_payload.data == b_payload.data; - } - } - if (a.cast(Payload.EnumSimple)) |a_payload| { - if (b.cast(Payload.EnumSimple)) |b_payload| { - return a_payload.data == b_payload.data; + + .single_const_pointer_to_comptime_int, + .const_slice_u8, + .const_slice_u8_sentinel_0, + .single_const_pointer, + .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .c_const_pointer, + .c_mut_pointer, + .const_slice, + .mut_slice, + .pointer, + .inferred_alloc_const, + .inferred_alloc_mut, + .manyptr_u8, + .manyptr_const_u8, + .manyptr_const_u8_sentinel_0, + => { + if (b.zigTypeTag() != .Pointer) return false; + + const info_a = a.ptrInfo().data; + const info_b = b.ptrInfo().data; + if (!info_a.pointee_type.eql(info_b.pointee_type)) + return false; + if (info_a.@"align" != info_b.@"align") + return false; + if (info_a.@"addrspace" != info_b.@"addrspace") + return false; + if (info_a.bit_offset != info_b.bit_offset) + return false; + if (info_a.host_size != info_b.host_size) + return false; + if (info_a.@"allowzero" != info_b.@"allowzero") + return false; + if (info_a.mutable != info_b.mutable) + return false; + if (info_a.@"volatile" != info_b.@"volatile") + return false; + if (info_a.size != info_b.size) + return false; + + const sentinel_a = info_a.sentinel; + const sentinel_b = info_b.sentinel; + if (sentinel_a) |sa| { + if (sentinel_b) |sb| { + if (!sa.eql(sb, info_a.pointee_type)) + return false; + } else { + return false; } + } else { + if (sentinel_b != null) + return false; } - return a.tag() == b.tag(); - }, - .Opaque => { - const opaque_obj_a = a.castTag(.@"opaque").?.data; - const opaque_obj_b = b.castTag(.@"opaque").?.data; - return opaque_obj_a == opaque_obj_b; + + return true; }, - .Union => { - if (a.cast(Payload.Union)) |a_payload| { - if (b.cast(Payload.Union)) |b_payload| { - return a_payload.data == b_payload.data; - } - } - return a.tag() == b.tag(); + + .optional, + .optional_single_const_pointer, + .optional_single_mut_pointer, + => { + if (b.zigTypeTag() != .Optional) return false; + + var buf_a: Payload.ElemType = undefined; + var buf_b: Payload.ElemType = undefined; + return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b)); }, - .ErrorUnion => { + + .anyerror_void_error_union, .error_union => { + if (b.zigTypeTag() != .ErrorUnion) return false; + const a_set = a.errorUnionSet(); const b_set = b.errorUnionSet(); if (!a_set.eql(b_set)) return false; @@ -693,34 +743,100 @@ pub const Type = extern union { return true; }, - .ErrorSet => { - // TODO: revisit the language specification for how to evaluate equality - // for error set types. - if (a.tag() == .anyerror and b.tag() == .anyerror) { - return true; - } + .anyframe_T => { + if (b.zigTypeTag() != .AnyFrame) return false; + return a.childType().eql(b.childType()); + }, - if (a.tag() == .error_set and b.tag() == .error_set) { - return a.castTag(.error_set).?.data.owner_decl == b.castTag(.error_set).?.data.owner_decl; - } + .empty_struct => { + const a_namespace = a.castTag(.empty_struct).?.data; + const b_namespace = (b.castTag(.empty_struct) orelse return false).data; + return a_namespace == b_namespace; + }, + .@"struct" => { + const a_struct_obj = a.castTag(.@"struct").?.data; + const b_struct_obj = (b.castTag(.@"struct") orelse return false).data; + return a_struct_obj == b_struct_obj; + }, + .tuple, .empty_struct_literal => { + if (!b.isTuple()) return false; - if (a.tag() == .error_set_inferred and b.tag() == .error_set_inferred) { - return a.castTag(.error_set_inferred).?.data == b.castTag(.error_set_inferred).?.data; + const a_tuple = a.tupleFields(); + const b_tuple = b.tupleFields(); + + if (a_tuple.types.len != b_tuple.types.len) return false; + + for (a_tuple.types) |a_ty, i| { + const b_ty = b_tuple.types[i]; + if (!eql(a_ty, b_ty)) return false; } - if (a.tag() == .error_set_single and b.tag() == .error_set_single) { - const a_data = a.castTag(.error_set_single).?.data; - const b_data = b.castTag(.error_set_single).?.data; - return std.mem.eql(u8, a_data, b_data); + for (a_tuple.values) |a_val, i| { + const ty = a_tuple.types[i]; + const b_val = b_tuple.values[i]; + if (a_val.tag() == .unreachable_value) { + if (b_val.tag() == .unreachable_value) { + continue; + } else { + return false; + } + } else { + if (b_val.tag() == .unreachable_value) { + return false; + } else { + if (!Value.eql(a_val, b_val, ty)) return false; + } + } } - return false; + + return true; }, - .Float => return a.tag() == b.tag(), - .BoundFn, - .Frame, - => std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }), + // we can't compare these based on tags because it wouldn't detect if, + // for example, a was resolved into .@"struct" but b was one of these tags. + .call_options, + .prefetch_options, + .export_options, + .extern_options, + => unreachable, // needed to resolve the type before now + + .enum_full, .enum_nonexhaustive => { + const a_enum_obj = a.cast(Payload.EnumFull).?.data; + const b_enum_obj = (b.cast(Payload.EnumFull) orelse return false).data; + return a_enum_obj == b_enum_obj; + }, + .enum_simple => { + const a_enum_obj = a.cast(Payload.EnumSimple).?.data; + const b_enum_obj = (b.cast(Payload.EnumSimple) orelse return false).data; + return a_enum_obj == b_enum_obj; + }, + .enum_numbered => { + const a_enum_obj = a.cast(Payload.EnumNumbered).?.data; + const b_enum_obj = (b.cast(Payload.EnumNumbered) orelse return false).data; + return a_enum_obj == b_enum_obj; + }, + // we can't compare these based on tags because it wouldn't detect if, + // for example, a was resolved into .enum_simple but b was one of these tags. + .atomic_order, + .atomic_rmw_op, + .calling_convention, + .address_space, + .float_mode, + .reduce_op, + => unreachable, // needed to resolve the type before now + + .@"union", .union_tagged => { + const a_union_obj = a.cast(Payload.Union).?.data; + const b_union_obj = (b.cast(Payload.Union) orelse return false).data; + return a_union_obj == b_union_obj; + }, + // we can't compare these based on tags because it wouldn't detect if, + // for example, a was resolved into .union_tagged but b was one of these tags. + .type_info => unreachable, // needed to resolve the type before now + + .bound_fn => unreachable, + .var_args_param => unreachable, // can be any type } } @@ -730,8 +846,8 @@ pub const Type = extern union { return hasher.final(); } - pub fn hashWithHasher(self: Type, hasher: *std.hash.Wyhash) void { - const zig_type_tag = self.zigTypeTag(); + pub fn hashWithHasher(ty: Type, hasher: *std.hash.Wyhash) void { + const zig_type_tag = ty.zigTypeTag(); std.hash.autoHash(hasher, zig_type_tag); switch (zig_type_tag) { .Type, @@ -745,41 +861,58 @@ pub const Type = extern union { => {}, // The zig type tag is all that is needed to distinguish. .Pointer => { - // TODO implement more pointer type hashing + const info = ty.ptrInfo().data; + hashWithHasher(info.pointee_type, hasher); + hashSentinel(info.sentinel, info.pointee_type, hasher); + std.hash.autoHash(hasher, info.@"align"); + std.hash.autoHash(hasher, info.@"addrspace"); + std.hash.autoHash(hasher, info.bit_offset); + std.hash.autoHash(hasher, info.host_size); + std.hash.autoHash(hasher, info.@"allowzero"); + std.hash.autoHash(hasher, info.mutable); + std.hash.autoHash(hasher, info.@"volatile"); + std.hash.autoHash(hasher, info.size); }, .Int => { // Detect that e.g. u64 != usize, even if the bits match on a particular target. - if (self.isNamedInt()) { - std.hash.autoHash(hasher, self.tag()); + if (ty.isNamedInt()) { + std.hash.autoHash(hasher, ty.tag()); } else { // Remaining cases are arbitrary sized integers. // The target will not be branched upon, because we handled target-dependent cases above. - const info = self.intInfo(@as(Target, undefined)); + const info = ty.intInfo(@as(Target, undefined)); std.hash.autoHash(hasher, info.signedness); std.hash.autoHash(hasher, info.bits); } }, .Array, .Vector => { - std.hash.autoHash(hasher, self.arrayLen()); - std.hash.autoHash(hasher, self.elemType().hash()); - // TODO hash array sentinel + const elem_ty = ty.elemType(); + std.hash.autoHash(hasher, ty.arrayLen()); + hashWithHasher(elem_ty, hasher); + hashSentinel(ty.sentinel(), elem_ty, hasher); }, .Fn => { - std.hash.autoHash(hasher, self.fnReturnType().hash()); - std.hash.autoHash(hasher, self.fnCallingConvention()); - const params_len = self.fnParamLen(); - std.hash.autoHash(hasher, params_len); - var i: usize = 0; - while (i < params_len) : (i += 1) { - std.hash.autoHash(hasher, self.fnParamType(i).hash()); + const fn_info = ty.fnInfo(); + hashWithHasher(fn_info.return_type, hasher); + std.hash.autoHash(hasher, fn_info.alignment); + std.hash.autoHash(hasher, fn_info.cc); + std.hash.autoHash(hasher, fn_info.is_var_args); + std.hash.autoHash(hasher, fn_info.is_generic); + + std.hash.autoHash(hasher, fn_info.param_types.len); + for (fn_info.param_types) |param_ty, i| { + std.hash.autoHash(hasher, fn_info.paramIsComptime(i)); + if (param_ty.tag() == .generic_poison) continue; + hashWithHasher(param_ty, hasher); } - std.hash.autoHash(hasher, self.fnIsVarArgs()); }, .Optional => { var buf: Payload.ElemType = undefined; - std.hash.autoHash(hasher, self.optionalChild(&buf).hash()); + hashWithHasher(ty.optionalChild(&buf), hasher); + }, + .Float => { + std.hash.autoHash(hasher, ty.tag()); }, - .Float, .Struct, .ErrorUnion, .ErrorSet, @@ -796,6 +929,15 @@ pub const Type = extern union { } } + fn hashSentinel(opt_val: ?Value, ty: Type, hasher: *std.hash.Wyhash) void { + if (opt_val) |s| { + std.hash.autoHash(hasher, true); + s.hash(ty, hasher); + } else { + std.hash.autoHash(hasher, false); + } + } + pub const HashContext64 = struct { pub fn hash(self: @This(), t: Type) u64 { _ = self; @@ -2834,8 +2976,8 @@ pub const Type = extern union { /// For [*]T, returns *T /// For []T, returns *T /// Handles const-ness and address spaces in particular. - pub fn elemPtrType(ptr_ty: Type, arena: Allocator) !Type { - return try Type.ptr(arena, .{ + pub fn elemPtrType(ptr_ty: Type, arena: Allocator, target: Target) !Type { + return try Type.ptr(arena, target, .{ .pointee_type = ptr_ty.elemType2(), .mutable = ptr_ty.ptrIsMutable(), .@"addrspace" = ptr_ty.ptrAddressSpace(), @@ -4635,6 +4777,8 @@ pub const Type = extern union { pointee_type: Type, sentinel: ?Value = null, /// If zero use pointee_type.abiAlignment() + /// When creating pointer types, if alignment is equal to pointee type + /// abi alignment, this value should be set to 0 instead. @"align": u32 = 0, /// See src/target.zig defaultAddressSpace function for how to obtain /// an appropriate value for this field. @@ -4643,6 +4787,8 @@ pub const Type = extern union { /// If this is non-zero it means the pointer points to a sub-byte /// range of data, which is backed by a "host integer" with this /// number of bytes. + /// When host_size=pointee_abi_size and bit_offset=0, this must be + /// represented with host_size=0 instead. host_size: u16 = 0, @"allowzero": bool = false, mutable: bool = true, // TODO rename this to const, not mutable @@ -4739,10 +4885,30 @@ pub const Type = extern union { pub const @"type" = initTag(.type); pub const @"anyerror" = initTag(.anyerror); - pub fn ptr(arena: Allocator, d: Payload.Pointer.Data) !Type { - assert(d.host_size == 0 or d.bit_offset < d.host_size * 8); + pub fn ptr(arena: Allocator, target: Target, data: Payload.Pointer.Data) !Type { + var d = data; + if (d.size == .C) { - assert(d.@"allowzero"); // All C pointers must set allowzero to true. + d.@"allowzero" = true; + } + + // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee + // type, we change it to 0 here. If this causes an assertion trip because the + // pointee type needs to be resolved more, that needs to be done before calling + // this ptr() function. + if (d.@"align" != 0 and d.@"align" == d.pointee_type.abiAlignment(target)) { + d.@"align" = 0; + } + + // Canonicalize host_size. If it matches the bit size of the pointee type, + // we change it to 0 here. If this causes an assertion trip, the pointee type + // needs to be resolved before calling this ptr() function. + if (d.host_size != 0) { + assert(d.bit_offset < d.host_size * 8); + if (d.host_size * 8 == d.pointee_type.bitSize(target)) { + assert(d.bit_offset == 0); + d.host_size = 0; + } } if (d.@"align" == 0 and d.@"addrspace" == .generic and @@ -4789,6 +4955,7 @@ pub const Type = extern union { return Type.initPayload(&type_payload.base); } } + return Type.Tag.pointer.create(arena, d); } diff --git a/test/behavior/align.zig b/test/behavior/align.zig index acdf484b15..37430f8854 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -6,6 +6,8 @@ const native_arch = builtin.target.cpu.arch; var foo: u8 align(4) = 100; test "global variable alignment" { + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); comptime try expect(@TypeOf(&foo) == *align(4) u8); { @@ -84,6 +86,8 @@ test "size of extern struct with 128-bit field" { } test "@ptrCast preserves alignment of bigger source" { + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + var x: u32 align(16) = 1234; const ptr = @ptrCast(*u8, &x); try expect(@TypeOf(ptr) == *align(16) u8); @@ -99,6 +103,7 @@ fn fnWithAlignedStack() i32 { } test "implicitly decreasing slice alignment" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -111,6 +116,7 @@ fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { } test "specifying alignment allows pointer cast" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -123,6 +129,7 @@ fn testBytesAlign(b: u8) !void { } test "@alignCast slices" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -260,9 +267,10 @@ fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 { } test "runtime known array index has best alignment possible" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO // take full advantage of over-alignment var array align(4) = [_]u8{ 1, 2, 3, 4 }; diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 58c676b7b8..2369f82d26 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -6,6 +6,7 @@ const expect = testing.expect; const expectEqual = testing.expectEqual; test "array to slice" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; diff --git a/test/behavior/ptrcast.zig b/test/behavior/ptrcast.zig index 02ae0fd0c6..2bc35e4286 100644 --- a/test/behavior/ptrcast.zig +++ b/test/behavior/ptrcast.zig @@ -63,6 +63,8 @@ const Bytes = struct { }; test "comptime ptrcast keeps larger alignment" { + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + comptime { const a: u32 = 1234; const p = @ptrCast([*]const u8, &a); diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 391de2e901..ea50e98e31 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -876,8 +876,6 @@ test "union no tag with struct member" { } test "union with comptime_int tag" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - const Union = union(enum(comptime_int)) { X: u32, Y: u16, -- cgit v1.2.3 From 1c8a86f063b65e95c2e23ceaa40843069adfdc23 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 2 Mar 2022 17:28:39 -0700 Subject: 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. --- src/Sema.zig | 162 ++++++++++++++++++++++++++++++++++----------- test/behavior.zig | 5 +- test/behavior/array.zig | 10 ++- test/behavior/cast.zig | 10 +-- test/behavior/floatop.zig | 104 ++++++++++++++++++++++++++--- test/behavior/inttoptr.zig | 3 +- test/behavior/struct.zig | 24 +++++-- test/behavior/switch.zig | 86 ++++++++++++++++++++++-- test/behavior/union.zig | 14 ++-- 9 files changed, 340 insertions(+), 78 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/Sema.zig b/src/Sema.zig index 2beeef0c6c..06a05ca30c 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2737,6 +2737,7 @@ fn zirValidateStructInit( init_src, instrs, object_ptr, + is_comptime, ), else => unreachable, } @@ -2749,6 +2750,7 @@ fn validateUnionInit( init_src: LazySrcLoc, instrs: []const Zir.Inst.Index, union_ptr: Air.Inst.Ref, + is_comptime: bool, ) CompileError!void { if (instrs.len != 1) { const msg = msg: { @@ -2771,6 +2773,11 @@ fn validateUnionInit( return sema.failWithOwnedErrorMsg(msg); } + if (is_comptime or block.is_comptime) { + // In this case, comptime machinery already did everything. No work to do here. + return; + } + const field_ptr = instrs[0]; const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node; const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_ptr_data.src_node }; @@ -2779,44 +2786,72 @@ fn validateUnionInit( const field_index_big = union_obj.fields.getIndex(field_name) orelse return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name); const field_index = @intCast(u32, field_index_big); - - // Handle the possibility of the union value being comptime-known. - const union_ptr_inst = Air.refToIndex(union_ptr).?; - switch (sema.air_instructions.items(.tag)[union_ptr_inst]) { - .constant => { - if (try sema.resolveDefinedValue(block, init_src, union_ptr)) |ptr_val| { - if (ptr_val.isComptimeMutablePtr()) { - // In this case the tag has already been set. No validation to do. - return; - } - } - }, - .bitcast => { - // TODO here we need to go back and see if we need to convert the union - // to a comptime-known value. In such case, we must delete all the instructions - // added to the current block starting with the bitcast. - // If the bitcast result ptr is an alloc, the alloc should be replaced with - // a constant decl_ref. - // Otherwise, the bitcast should be preserved and a store instruction should be - // emitted to store the constant union value through the bitcast. - }, - .alloc => {}, - else => |t| { - if (std.debug.runtime_safety) { - std.debug.panic("unexpected AIR tag for union pointer: {s}", .{@tagName(t)}); - } else { - unreachable; - } - }, + const air_tags = sema.air_instructions.items(.tag); + const air_datas = sema.air_instructions.items(.data); + const field_ptr_air_ref = sema.inst_map.get(field_ptr).?; + const field_ptr_air_inst = Air.refToIndex(field_ptr_air_ref).?; + + // Our task here is to determine if the union is comptime-known. In such case, + // we erase the runtime AIR instructions for initializing the union, and replace + // the mapping with the comptime value. Either way, we will need to populate the tag. + + // We expect to see something like this in the current block AIR: + // %a = alloc(*const U) + // %b = bitcast(*U, %a) + // %c = field_ptr(..., %b) + // %e!= store(%c!, %d!) + // If %d is a comptime operand, the union is comptime. + // If the union is comptime, we want `first_block_index` + // to point at %c so that the bitcast becomes the last instruction in the block. + // + // In the case of a comptime-known pointer to a union, the + // the field_ptr instruction is missing, so we have to pattern-match + // based only on the store instructions. + // `first_block_index` needs to point to the `field_ptr` if it exists; + // the `store` otherwise. + // + // It's also possible for there to be no store instruction, in the case + // of nested `coerce_result_ptr` instructions. If we see the `field_ptr` + // but we have not found a `store`, treat as a runtime-known field. + var first_block_index = block.instructions.items.len; + var block_index = block.instructions.items.len - 1; + var init_val: ?Value = null; + while (block_index > 0) : (block_index -= 1) { + const store_inst = block.instructions.items[block_index]; + if (store_inst == field_ptr_air_inst) break; + if (air_tags[store_inst] != .store) continue; + const bin_op = air_datas[store_inst].bin_op; + if (bin_op.lhs != field_ptr_air_ref) continue; + if (block_index > 0 and + field_ptr_air_inst == block.instructions.items[block_index - 1]) + { + first_block_index = @minimum(first_block_index, block_index - 1); + } else { + first_block_index = @minimum(first_block_index, block_index); + } + init_val = try sema.resolveMaybeUndefValAllowVariables(block, init_src, bin_op.rhs); + break; } - // Otherwise, we set the new union tag now. - const new_tag = try sema.addConstant( - union_obj.tag_ty, - try Value.Tag.enum_field_index.create(sema.arena, field_index), - ); + const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index); + + if (init_val) |val| { + // Our task is to delete all the `field_ptr` and `store` instructions, and insert + // instead a single `store` to the result ptr with a comptime union value. + block.instructions.shrinkRetainingCapacity(first_block_index); + + const union_val = try Value.Tag.@"union".create(sema.arena, .{ + .tag = tag_val, + .val = val, + }); + const union_ty = sema.typeOf(union_ptr).childType(); + const union_init = try sema.addConstant(union_ty, union_val); + try sema.storePtr2(block, init_src, union_ptr, init_src, union_init, init_src, .store); + return; + } try sema.requireRuntimeBlock(block, init_src); + const new_tag = try sema.addConstant(union_obj.tag_ty, tag_val); _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag); } @@ -3084,7 +3119,7 @@ fn zirValidateArrayInit( } var array_is_comptime = true; - var first_block_index: usize = std.math.maxInt(u32); + var first_block_index = block.instructions.items.len; // Collect the comptime element values in case the array literal ends up // being comptime-known. @@ -15147,7 +15182,32 @@ fn unionFieldPtr( }); if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| { - // TODO detect inactive union field and emit compile error + switch (union_obj.layout) { + .Auto => { + // TODO emit the access of inactive union field error commented out below. + // In order to do that, we need to first solve the problem that AstGen + // emits field_ptr instructions in order to initialize union values. + // In such case we need to know that the field_ptr instruction (which is + // calling this unionFieldPtr function) is *initializing* the union, + // in which case we would skip this check, and in fact we would actually + // set the union tag here and the payload to undefined. + + //const tag_and_val = union_val.castTag(.@"union").?.data; + //var field_tag_buf: Value.Payload.U32 = .{ + // .base = .{ .tag = .enum_field_index }, + // .data = field_index, + //}; + //const field_tag = Value.initPayload(&field_tag_buf.base); + //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty); + //if (!tag_matches) { + // // TODO enhance this saying which one was active + // // and which one was accessed, and showing where the union was declared. + // return sema.fail(block, src, "access of inactive union field", .{}); + //} + // TODO add runtime safety check for the active tag + }, + .Packed, .Extern => {}, + } return sema.addConstant( ptr_field_ty, try Value.Tag.field_ptr.create(arena, .{ @@ -15183,9 +15243,33 @@ fn unionFieldVal( if (try sema.resolveMaybeUndefVal(block, src, union_byval)) |union_val| { if (union_val.isUndef()) return sema.addConstUndef(field.ty); - // TODO detect inactive union field and emit compile error - const active_val = union_val.castTag(.@"union").?.data.val; - return sema.addConstant(field.ty, active_val); + const tag_and_val = union_val.castTag(.@"union").?.data; + var field_tag_buf: Value.Payload.U32 = .{ + .base = .{ .tag = .enum_field_index }, + .data = field_index, + }; + const field_tag = Value.initPayload(&field_tag_buf.base); + const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty); + switch (union_obj.layout) { + .Auto => { + if (tag_matches) { + return sema.addConstant(field.ty, tag_and_val.val); + } else { + // TODO enhance this saying which one was active + // and which one was accessed, and showing where the union was declared. + return sema.fail(block, src, "access of inactive union field", .{}); + } + }, + .Packed, .Extern => { + if (tag_matches) { + return sema.addConstant(field.ty, tag_and_val.val); + } else { + const old_ty = union_ty.unionFieldType(tag_and_val.tag); + const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty); + return sema.addConstant(field.ty, new_val); + } + }, + } } try sema.requireRuntimeBlock(block, src); diff --git a/test/behavior.zig b/test/behavior.zig index d620c24711..85023a7469 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -51,6 +51,7 @@ test { _ = @import("behavior/defer.zig"); _ = @import("behavior/enum.zig"); _ = @import("behavior/error.zig"); + _ = @import("behavior/floatop.zig"); _ = @import("behavior/fn.zig"); _ = @import("behavior/fn_delegation.zig"); _ = @import("behavior/fn_in_struct_in_comptime.zig"); @@ -79,6 +80,7 @@ test { _ = @import("behavior/slice_sentinel_comptime.zig"); _ = @import("behavior/src.zig"); _ = @import("behavior/struct.zig"); + _ = @import("behavior/switch.zig"); _ = @import("behavior/this.zig"); _ = @import("behavior/truncate.zig"); _ = @import("behavior/try.zig"); @@ -93,7 +95,6 @@ test { _ = @import("behavior/void.zig"); _ = @import("behavior/while.zig"); - // tests that don't pass for stage1 if (builtin.zig_backend != .stage1) { _ = @import("behavior/decltest.zig"); } @@ -116,13 +117,11 @@ test { if (builtin.zig_backend != .stage2_c) { // Tests that pass for stage1 and the llvm backend. _ = @import("behavior/atomics.zig"); - _ = @import("behavior/floatop.zig"); _ = @import("behavior/math.zig"); _ = @import("behavior/maximum_minimum.zig"); _ = @import("behavior/popcount.zig"); _ = @import("behavior/saturating_arithmetic.zig"); _ = @import("behavior/sizeof_and_typeof.zig"); - _ = @import("behavior/switch.zig"); _ = @import("behavior/widening.zig"); _ = @import("behavior/bugs/421.zig"); _ = @import("behavior/bugs/726.zig"); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 5df6851ab2..634be7f5ad 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -108,15 +108,19 @@ test "array len field" { } test "array with sentinels" { + if (builtin.zig_backend == .stage1) { + // Stage1 test coverage disabled at runtime because of + // https://github.com/ziglang/zig/issues/4372 + return error.SkipZigTest; + } + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest(is_ct: bool) !void { - if (is_ct or builtin.zig_backend != .stage1) { + { var zero_sized: [0:0xde]u8 = [_:0xde]u8{}; - // Stage1 test coverage disabled at runtime because of - // https://github.com/ziglang/zig/issues/4372 try expect(zero_sized[0] == 0xde); var reinterpreted = @ptrCast(*[1]u8, &zero_sized); try expect(reinterpreted[0] == 0xde); diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 60eacfee5d..bc120d6697 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1050,9 +1050,9 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void { } test "compile time int to ptr of function" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO + + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO @@ -1060,11 +1060,13 @@ test "compile time int to ptr of function" { try foobar(FUNCTION_CONSTANT); } -pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize)); +// On some architectures function pointers must be aligned. +const hardcoded_fn_addr = maxInt(usize) & ~@as(usize, 0xf); +pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, hardcoded_fn_addr); pub const PFN_void = *const fn (*anyopaque) callconv(.C) void; fn foobar(func: PFN_void) !void { - try std.testing.expect(@ptrToInt(func) == maxInt(usize)); + try std.testing.expect(@ptrToInt(func) == hardcoded_fn_addr); } test "implicit ptr to *anyopaque" { diff --git a/test/behavior/floatop.zig b/test/behavior/floatop.zig index 5597be122e..1b3652fa6a 100644 --- a/test/behavior/floatop.zig +++ b/test/behavior/floatop.zig @@ -21,6 +21,12 @@ fn epsForType(comptime T: type) T { } test "floating point comparisons" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try testFloatComparisons(); comptime try testFloatComparisons(); } @@ -51,6 +57,12 @@ fn testFloatComparisons() !void { } test "different sized float comparisons" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try testDifferentSizedFloatComparisons(); comptime try testDifferentSizedFloatComparisons(); } @@ -81,12 +93,24 @@ fn testDifferentSizedFloatComparisons() !void { //} test "negative f128 floatToInt at compile-time" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const a: f128 = -2; var b = @floatToInt(i64, a); try expect(@as(i64, -2) == b); } test "@sqrt" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + comptime try testSqrt(); try testSqrt(); } @@ -129,6 +153,12 @@ fn testSqrt() !void { } test "more @sqrt f16 tests" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + // TODO these are not all passing at comptime try expect(@sqrt(@as(f16, 0.0)) == 0.0); try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon)); @@ -149,14 +179,21 @@ test "more @sqrt f16 tests" { } test "@sin" { + if (builtin.zig_backend == .stage1) { + // stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)` + return error.SkipZigTest; + } + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + comptime try testSin(); try testSin(); } fn testSin() !void { - // stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)` - if (builtin.zig_backend == .stage1) return error.SkipZigTest; - inline for ([_]type{ f16, f32, f64 }) |ty| { const eps = epsForType(ty); try expect(@sin(@as(ty, 0)) == 0); @@ -176,14 +213,21 @@ fn testSin() !void { } test "@cos" { + if (builtin.zig_backend == .stage1) { + // stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)` + return error.SkipZigTest; + } + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + comptime try testCos(); try testCos(); } fn testCos() !void { - // stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)` - if (builtin.zig_backend == .stage1) return error.SkipZigTest; - inline for ([_]type{ f16, f32, f64 }) |ty| { const eps = epsForType(ty); try expect(@cos(@as(ty, 0)) == 1); @@ -203,6 +247,12 @@ fn testCos() !void { } test "@exp" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + comptime try testExp(); try testExp(); } @@ -226,6 +276,12 @@ fn testExp() !void { } test "@exp2" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + comptime try testExp2(); try testExp2(); } @@ -249,7 +305,7 @@ fn testExp2() !void { } test "@log" { - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO comptime try testLog(); try testLog(); @@ -285,7 +341,7 @@ fn testLog() !void { } test "@log2" { - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO comptime try testLog2(); try testLog2(); @@ -310,7 +366,7 @@ fn testLog2() !void { } test "@log10" { - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO comptime try testLog10(); try testLog10(); @@ -335,6 +391,12 @@ fn testLog10() !void { } test "@fabs" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + comptime try testFabs(); try testFabs(); } @@ -367,6 +429,12 @@ fn testFabs() !void { } test "@floor" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + comptime try testFloor(); try testFloor(); } @@ -394,6 +462,12 @@ fn testFloor() !void { } test "@ceil" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + comptime try testCeil(); try testCeil(); } @@ -421,6 +495,12 @@ fn testCeil() !void { } test "@trunc" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + comptime try testTrunc(); try testTrunc(); } @@ -449,7 +529,11 @@ fn testTrunc() !void { test "negation" { if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - if (builtin.os.tag == .freebsd) return error.SkipZigTest; + + if (builtin.os.tag == .freebsd) { + // TODO file issue to track this failure + return error.SkipZigTest; + } const S = struct { fn doTheTest() !void { diff --git a/test/behavior/inttoptr.zig b/test/behavior/inttoptr.zig index 8a642d7803..4b8f6ac161 100644 --- a/test/behavior/inttoptr.zig +++ b/test/behavior/inttoptr.zig @@ -2,7 +2,6 @@ const builtin = @import("builtin"); test "casting integer address to function pointer" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; @@ -11,7 +10,7 @@ test "casting integer address to function pointer" { } fn addressToFunction() void { - var addr: usize = 0xdeadbeef; + var addr: usize = 0xdeadbee0; _ = @intToPtr(*const fn () void, addr); } diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index a09b434d01..307f0fc85f 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -1175,7 +1175,11 @@ test "for loop over pointers to struct, getting field from struct pointer" { test "anon init through error unions and optionals" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { a: u32, @@ -1200,7 +1204,11 @@ test "anon init through error unions and optionals" { test "anon init through optional" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { a: u32, @@ -1218,7 +1226,11 @@ test "anon init through optional" { test "anon init through error union" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { a: u32, @@ -1236,7 +1248,11 @@ test "anon init through error union" { test "typed init through error unions and optionals" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { a: u32, diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index 07b6c4b9f1..22c78e3162 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -1,9 +1,13 @@ +const builtin = @import("builtin"); const std = @import("std"); const expect = std.testing.expect; const expectError = std.testing.expectError; const expectEqual = std.testing.expectEqual; test "switch with numbers" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try testSwitchWithNumbers(13); } @@ -17,6 +21,9 @@ fn testSwitchWithNumbers(x: u32) !void { } test "switch with all ranges" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try expect(testSwitchWithAllRanges(50, 3) == 1); try expect(testSwitchWithAllRanges(101, 0) == 2); try expect(testSwitchWithAllRanges(300, 5) == 3); @@ -48,6 +55,9 @@ test "implicit comptime switch" { } test "switch on enum" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const fruit = Fruit.Orange; nonConstSwitchOnEnum(fruit); } @@ -65,6 +75,9 @@ fn nonConstSwitchOnEnum(fruit: Fruit) void { } test "switch statement" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try nonConstSwitch(SwitchStatementFoo.C); } fn nonConstSwitch(foo: SwitchStatementFoo) !void { @@ -79,6 +92,10 @@ fn nonConstSwitch(foo: SwitchStatementFoo) !void { const SwitchStatementFoo = enum { A, B, C, D }; test "switch with multiple expressions" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const x = switch (returnsFive()) { 1, 2, 3 => 1, 4, 5, 6 => 2, @@ -91,6 +108,9 @@ fn returnsFive() i32 { } test "switch on type" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try expect(trueIfBoolFalseOtherwise(bool)); try expect(!trueIfBoolFalseOtherwise(i32)); } @@ -103,6 +123,10 @@ fn trueIfBoolFalseOtherwise(comptime T: type) bool { } test "switching on booleans" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try testSwitchOnBools(); comptime try testSwitchOnBools(); } @@ -154,6 +178,9 @@ test "undefined.u0" { } test "switch with disjoint range" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + var q: u8 = 0; switch (q) { 0...125 => {}, @@ -163,6 +190,9 @@ test "switch with disjoint range" { } test "switch variable for range and multiple prongs" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const S = struct { fn doTheTest() !void { var u: u8 = 16; @@ -196,6 +226,9 @@ fn poll() void { } test "switch on global mutable var isn't constant-folded" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + while (state < 2) { poll(); } @@ -208,6 +241,10 @@ const SwitchProngWithVarEnum = union(enum) { }; test "switch prong with variable" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 }); try switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 }); try switchProngWithVarFn(SwitchProngWithVarEnum{ .Meh = {} }); @@ -228,6 +265,9 @@ fn switchProngWithVarFn(a: SwitchProngWithVarEnum) !void { } test "switch on enum using pointer capture" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try testSwitchEnumPtrCapture(); comptime try testSwitchEnumPtrCapture(); } @@ -245,6 +285,10 @@ fn testSwitchEnumPtrCapture() !void { } test "switch handles all cases of number" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try testSwitchHandleAllCases(); comptime try testSwitchHandleAllCases(); } @@ -282,6 +326,9 @@ fn testSwitchHandleAllCasesRange(x: u8) u8 { } test "switch on union with some prongs capturing" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const X = union(enum) { a, b: i32, @@ -311,10 +358,16 @@ fn returnsFalse() bool { } } test "switch on const enum with var" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try expect(!returnsFalse()); } test "anon enum literal used in switch on union enum" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const Foo = union(enum) { a: i32, }; @@ -328,6 +381,9 @@ test "anon enum literal used in switch on union enum" { } test "switch all prongs unreachable" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + try testAllProngsUnreachable(); comptime try testAllProngsUnreachable(); } @@ -349,6 +405,9 @@ fn switchWithUnreachable(x: i32) i32 { } test "capture value of switch with all unreachable prongs" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const x = return_a_number() catch |err| switch (err) { else => unreachable, }; @@ -360,6 +419,10 @@ fn return_a_number() anyerror!i32 { } test "switch on integer with else capturing expr" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const S = struct { fn doTheTest() !void { var x: i32 = 5; @@ -375,7 +438,7 @@ test "switch on integer with else capturing expr" { } test "else prong of switch on error set excludes other cases" { - if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -407,7 +470,7 @@ test "else prong of switch on error set excludes other cases" { } test "switch prongs with error set cases make a new error set type for capture value" { - if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -441,6 +504,9 @@ test "switch prongs with error set cases make a new error set type for capture v } test "return result loc and then switch with range implicit casted to error union" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const S = struct { fn doTheTest() !void { 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 } test "switch with null and T peer types and inferred result location type" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const S = struct { fn doTheTest(c: u8) !void { if (switch (c) { @@ -473,7 +543,7 @@ test "switch with null and T peer types and inferred result location type" { } test "switch prongs with cases with identical payload types" { - if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO const Union = union(enum) { A: usize, @@ -515,7 +585,11 @@ test "switch prongs with cases with identical payload types" { } test "switch on pointer type" { - if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { const X = struct { @@ -544,7 +618,7 @@ test "switch on pointer type" { } test "switch on error set with single else" { - if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -563,7 +637,7 @@ test "switch on error set with single else" { } test "switch capture copies its payload" { - if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO + if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { diff --git a/test/behavior/union.zig b/test/behavior/union.zig index d352139358..224100f5ab 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -878,8 +878,6 @@ test "union with comptime_int tag" { } test "extern union doesn't trigger field check at comptime" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - const U = extern union { x: u32, y: u8, @@ -890,7 +888,8 @@ test "extern union doesn't trigger field check at comptime" { } test "anonymous union literal syntax" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { const Number = union { @@ -914,7 +913,8 @@ test "anonymous union literal syntax" { } test "function call result coerces from tagged union to the tag" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { const Arch = union(enum) { @@ -1104,9 +1104,9 @@ test "union enum type gets a separate scope" { test "global variable struct contains union initialized to non-most-aligned field" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const T = struct { const U = union(enum) { -- cgit v1.2.3 From 3ec74a1cd8b868b7cebfd584dec3f20a9aa2bda6 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 3 Mar 2022 00:03:54 +0100 Subject: codegen: handle elem_ptr when lowering to memory * x64: handle storing from-to non-stack memory --- src/arch/x86_64/CodeGen.zig | 37 +++++++++++++++++++++++++++++++++++++ src/codegen.zig | 24 ++++++++++++++++++++++++ test/behavior/array.zig | 4 ---- 3 files changed, 61 insertions(+), 4 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 79e5c88050..33fd2c8321 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2599,6 +2599,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type defer value.unfreezeIfRegister(&self.register_manager); const addr_reg = try self.register_manager.allocReg(null); + self.register_manager.freezeRegs(&.{addr_reg}); + defer self.register_manager.unfreezeRegs(&.{addr_reg}); + try self.loadMemPtrIntoRegister(addr_reg, ptr_ty, ptr); // to get the actual address of the value we want to modify we have to go through the GOT @@ -2662,6 +2665,40 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type .data = .{ .imm = 0 }, }); }, + .got_load, + .direct_load, + .memory, + => { + if (abi_size <= 8) { + const tmp_reg = try self.register_manager.allocReg(null); + self.register_manager.freezeRegs(&.{tmp_reg}); + defer self.register_manager.unfreezeRegs(&.{tmp_reg}); + + try self.loadMemPtrIntoRegister(tmp_reg, value_ty, value); + + _ = try self.addInst(.{ + .tag = .mov, + .ops = (Mir.Ops{ + .reg1 = tmp_reg, + .reg2 = tmp_reg, + .flags = 0b01, + }).encode(), + .data = .{ .imm = 0 }, + }); + _ = try self.addInst(.{ + .tag = .mov, + .ops = (Mir.Ops{ + .reg1 = addr_reg.to64(), + .reg2 = tmp_reg, + .flags = 0b10, + }).encode(), + .data = .{ .imm = 0 }, + }); + return; + } + + try self.genInlineMemcpy(.{ .register = addr_reg.to64() }, value, .{ .immediate = abi_size }, .{}); + }, else => return self.fail("TODO implement storing {} to MCValue.memory", .{value}), } }, diff --git a/src/codegen.zig b/src/codegen.zig index f0cf8da3b3..265c205f2f 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -392,6 +392,30 @@ pub fn generateSymbol( }, } }, + .elem_ptr => { + const elem_ptr = typed_value.val.castTag(.elem_ptr).?.data; + const elem_size = typed_value.ty.childType().abiSize(target); + const addend = @intCast(u32, elem_ptr.index * elem_size); + const array_ptr = elem_ptr.array_ptr; + + switch (array_ptr.tag()) { + .decl_ref => { + const decl = array_ptr.castTag(.decl_ref).?.data; + return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output, .{ + .parent_atom_index = reloc_info.parent_atom_index, + .addend = (reloc_info.addend orelse 0) + addend, + }); + }, + else => return Result{ + .fail = try ErrorMsg.create( + bin_file.allocator, + src_loc, + "TODO implement generateSymbol for pointer type value: '{s}'", + .{@tagName(typed_value.val.tag())}, + ), + }, + } + }, else => return Result{ .fail = try ErrorMsg.create( bin_file.allocator, diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 634be7f5ad..cf9eaf660c 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -179,7 +179,6 @@ fn plusOne(x: u32) u32 { test "single-item pointer to array indexing and slicing" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try testSingleItemPtrArrayIndexSlice(); @@ -206,7 +205,6 @@ fn doSomeMangling(array: *[4]u8) void { test "implicit cast zero sized array ptr to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; { @@ -244,7 +242,6 @@ const Str = struct { a: []Sub }; test "set global var array via slice embedded in struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var s = Str{ .a = s_array[0..] }; @@ -261,7 +258,6 @@ test "set global var array via slice embedded in struct" { test "read/write through global variable array of struct fields initialized via array mult" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { -- cgit v1.2.3 From a06e9eca45f72b28ed9ca00da5c9562e969cc84d Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Sat, 5 Mar 2022 11:31:51 +0100 Subject: stage2 AArch64: add more slice support * airSlice * airArrayToSlice * and initial support for airSlicePtr and co --- src/arch/aarch64/CodeGen.zig | 83 ++++++++++++++++++++++++++++++++++------ test/behavior/align.zig | 1 - test/behavior/array.zig | 2 - test/behavior/bitcast.zig | 10 ----- test/behavior/bugs/3367.zig | 1 - test/behavior/bugs/3586.zig | 2 - test/behavior/bugs/704.zig | 2 - test/behavior/cast.zig | 2 - test/behavior/defer.zig | 4 -- test/behavior/enum.zig | 40 ------------------- test/behavior/error.zig | 13 ------- test/behavior/floatop.zig | 2 - test/behavior/fn.zig | 20 ---------- test/behavior/for.zig | 6 --- test/behavior/generics.zig | 9 ----- test/behavior/if.zig | 8 ---- test/behavior/inttoptr.zig | 1 - test/behavior/math.zig | 2 - test/behavior/null.zig | 2 - test/behavior/slice.zig | 2 - test/behavior/struct.zig | 3 -- test/behavior/switch.zig | 4 -- test/behavior/this.zig | 2 - test/behavior/truncate.zig | 16 -------- test/behavior/try.zig | 4 -- test/behavior/usingnamespace.zig | 8 ---- test/behavior/while.zig | 2 - 27 files changed, 71 insertions(+), 180 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index cc7591ff34..b3447f43e7 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -818,9 +818,7 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { if (reg_ok) { // Make sure the type can fit in a register before we try to allocate one. - const ptr_bits = self.target.cpu.arch.ptrBitWidth(); - const ptr_bytes: u64 = @divExact(ptr_bits, 8); - if (abi_size <= ptr_bytes) { + if (abi_size <= 8) { if (self.register_manager.tryAllocReg(inst)) |reg| { return MCValue{ .register = registerAlias(reg, abi_size) }; } @@ -1038,7 +1036,20 @@ fn airMax(self: *Self, inst: Air.Inst.Index) !void { fn airSlice(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ptr = try self.resolveInst(bin_op.lhs); + const ptr_ty = self.air.typeOf(bin_op.lhs); + const len = try self.resolveInst(bin_op.rhs); + const len_ty = self.air.typeOf(bin_op.rhs); + + const ptr_bits = self.target.cpu.arch.ptrBitWidth(); + const ptr_bytes = @divExact(ptr_bits, 8); + + const stack_offset = try self.allocMem(inst, ptr_bytes * 2, ptr_bytes * 2); + try self.genSetStack(ptr_ty, stack_offset + ptr_bytes, ptr); + try self.genSetStack(len_ty, stack_offset, len); + break :result MCValue{ .stack_offset = stack_offset }; + }; return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -1602,22 +1613,39 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ptr_bits = self.target.cpu.arch.ptrBitWidth(); + const ptr_bytes = @divExact(ptr_bits, 8); + const mcv = try self.resolveInst(ty_op.operand); + switch (mcv) { + .dead, .unreach, .none => unreachable, + .register => unreachable, // a slice doesn't fit in one register + .stack_offset => |off| { + break :result MCValue{ .stack_offset = off + ptr_bytes }; + }, + .memory => |addr| { + break :result MCValue{ .memory = addr }; + }, + else => return self.fail("TODO implement slice_len for {}", .{mcv}), + } + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ptr_bits = self.target.cpu.arch.ptrBitWidth(); + const ptr_bytes = @divExact(ptr_bits, 8); const mcv = try self.resolveInst(ty_op.operand); switch (mcv) { - .dead, .unreach => unreachable, + .dead, .unreach, .none => unreachable, .register => unreachable, // a slice doesn't fit in one register .stack_offset => |off| { break :result MCValue{ .stack_offset = off }; }, .memory => |addr| { - break :result MCValue{ .memory = addr + 8 }; + break :result MCValue{ .memory = addr + ptr_bytes }; }, else => return self.fail("TODO implement slice_len for {}", .{mcv}), } @@ -1627,13 +1655,33 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ptr_bits = self.target.cpu.arch.ptrBitWidth(); + const ptr_bytes = @divExact(ptr_bits, 8); + const mcv = try self.resolveInst(ty_op.operand); + switch (mcv) { + .dead, .unreach, .none => unreachable, + .ptr_stack_offset => |off| { + break :result MCValue{ .ptr_stack_offset = off + ptr_bytes }; + }, + else => return self.fail("TODO implement ptr_slice_len_ptr for {}", .{mcv}), + } + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const mcv = try self.resolveInst(ty_op.operand); + switch (mcv) { + .dead, .unreach, .none => unreachable, + .ptr_stack_offset => |off| { + break :result MCValue{ .ptr_stack_offset = off }; + }, + else => return self.fail("TODO implement ptr_slice_len_ptr for {}", .{mcv}), + } + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -3475,9 +3523,20 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airArrayToSlice for {}", .{ - self.target.cpu.arch, - }); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ptr_ty = self.air.typeOf(ty_op.operand); + const ptr = try self.resolveInst(ty_op.operand); + const array_ty = ptr_ty.childType(); + const array_len = @intCast(u32, array_ty.arrayLen()); + + const ptr_bits = self.target.cpu.arch.ptrBitWidth(); + const ptr_bytes = @divExact(ptr_bits, 8); + + const stack_offset = try self.allocMem(inst, ptr_bytes * 2, ptr_bytes * 2); + try self.genSetStack(ptr_ty, stack_offset + ptr_bytes, ptr); + try self.genSetStack(Type.initTag(.usize), stack_offset, .{ .immediate = array_len }); + break :result MCValue{ .stack_offset = stack_offset }; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 461fd852e4..a0f05e5c1c 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -269,7 +269,6 @@ fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 { test "runtime known array index has best alignment possible" { if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO // take full advantage of over-alignment diff --git a/test/behavior/array.zig b/test/behavior/array.zig index cf9eaf660c..6482c1db2d 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -142,8 +142,6 @@ test "array with sentinels" { } test "void arrays" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var array: [4]void = undefined; array[0] = void{}; array[1] = array[2]; diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index 2b3c19da2a..6f647cbc79 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -75,8 +75,6 @@ fn conv_uN(comptime N: usize, x: std.meta.Int(.unsigned, N)) std.meta.Int(.signe } test "nested bitcast" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const S = struct { fn moo(x: isize) !void { try expect(@intCast(isize, 42) == x); @@ -94,8 +92,6 @@ test "nested bitcast" { } test "@bitCast enum to its integer type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const SOCK = enum(c_int) { A, B, @@ -113,15 +109,11 @@ test "@bitCast enum to its integer type" { // issue #3010: compiler segfault test "bitcast literal [4]u8 param to u32" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const ip = @bitCast(u32, [_]u8{ 255, 255, 255, 255 }); try expect(ip == maxInt(u32)); } test "bitcast generates a temporary value" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var y = @as(u16, 0x55AA); const x = @bitCast(u16, @bitCast([2]u8, y)); try expect(y == x); @@ -240,7 +232,6 @@ test "implicit cast to error union by returning" { test "bitcast packed struct literal to byte" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Foo = packed struct { value: u8, @@ -252,7 +243,6 @@ test "bitcast packed struct literal to byte" { test "comptime bitcast used in expression has the correct type" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Foo = packed struct { value: u8, diff --git a/test/behavior/bugs/3367.zig b/test/behavior/bugs/3367.zig index 4509283457..bd289af2b4 100644 --- a/test/behavior/bugs/3367.zig +++ b/test/behavior/bugs/3367.zig @@ -10,7 +10,6 @@ const Mixin = struct { }; test "container member access usingnamespace decls" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; var foo = Foo{}; foo.two(); diff --git a/test/behavior/bugs/3586.zig b/test/behavior/bugs/3586.zig index e61ed19616..c33e2e601f 100644 --- a/test/behavior/bugs/3586.zig +++ b/test/behavior/bugs/3586.zig @@ -7,8 +7,6 @@ const Container = struct { }; test "fixed" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var ctr = Container{ .params = NoteParams{}, }; diff --git a/test/behavior/bugs/704.zig b/test/behavior/bugs/704.zig index f15ddab726..a3fb786da4 100644 --- a/test/behavior/bugs/704.zig +++ b/test/behavior/bugs/704.zig @@ -6,8 +6,6 @@ const xxx = struct { } }; test "bug 704" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var x: xxx = undefined; x.bar(); } diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 70fe65d1b1..f3037c2d09 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -984,7 +984,6 @@ test "peer type resolve array pointers, one of them const" { test "peer type resolve array pointer and unknown pointer" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -1255,7 +1254,6 @@ test "assignment to optional pointer result loc" { } test "cast between *[N]void and []void" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var a: [4]void = undefined; diff --git a/test/behavior/defer.zig b/test/behavior/defer.zig index 5f41af8f56..cad06a7ed7 100644 --- a/test/behavior/defer.zig +++ b/test/behavior/defer.zig @@ -5,8 +5,6 @@ const expectEqual = std.testing.expectEqual; const expectError = std.testing.expectError; test "break and continue inside loop inside defer expression" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - testBreakContInDefer(10); comptime testBreakContInDefer(10); } @@ -23,8 +21,6 @@ fn testBreakContInDefer(x: usize) void { } test "defer and labeled break" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var i = @as(usize, 0); blk: { diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 161f63b156..3f41b45342 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -11,8 +11,6 @@ fn shouldEqual(n: Number, expected: u3) !void { } test "enum to int" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try shouldEqual(Number.Zero, 0); try shouldEqual(Number.One, 1); try shouldEqual(Number.Two, 2); @@ -558,8 +556,6 @@ const ValueCount257 = enum { }; test "enum sizes" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - comptime { try expect(@sizeOf(ValueCount1) == 0); try expect(@sizeOf(ValueCount2) == 1); @@ -569,8 +565,6 @@ test "enum sizes" { } test "enum literal equality" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const x = .hi; const y = .ok; const z = .hi; @@ -580,8 +574,6 @@ test "enum literal equality" { } test "enum literal cast to enum" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const Color = enum { Auto, Off, On }; var color1: Color = .Auto; @@ -590,8 +582,6 @@ test "enum literal cast to enum" { } test "peer type resolution with enum literal" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const Items = enum { one, two }; try expect(Items.two == .two); @@ -668,8 +658,6 @@ test "non-exhaustive enum" { } test "empty non-exhaustive enum" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const S = struct { const E = enum(u8) { _ }; @@ -732,8 +720,6 @@ const EnumWithTagValues = enum(u4) { D = 1 << 3, }; test "enum with tag values don't require parens" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try expect(@enumToInt(EnumWithTagValues.C) == 0b0100); } @@ -750,8 +736,6 @@ const MultipleChoice2 = enum(u32) { }; test "cast integer literal to enum" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try expect(@intToEnum(MultipleChoice2, 0) == MultipleChoice2.Unspecified1); try expect(@intToEnum(MultipleChoice2, 40) == MultipleChoice2.B); } @@ -783,8 +767,6 @@ const Small2 = enum(u2) { One, Two }; const Small = enum(u2) { One, Two, Three, Four }; test "set enum tag type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - { var x = Small.One; x = Small.Two; @@ -798,8 +780,6 @@ test "set enum tag type" { } test "casting enum to its tag type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try testCastEnumTag(Small2.Two); comptime try testCastEnumTag(Small2.Two); } @@ -809,8 +789,6 @@ fn testCastEnumTag(value: Small2) !void { } test "enum with 1 field but explicit tag type should still have the tag type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const Enum = enum(u8) { B = 2, }; @@ -818,8 +796,6 @@ test "enum with 1 field but explicit tag type should still have the tag type" { } test "signed integer as enum tag" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const SignedEnum = enum(i2) { A0 = -1, A1 = 0, @@ -832,8 +808,6 @@ test "signed integer as enum tag" { } test "enum with one member and custom tag type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const E = enum(u2) { One, }; @@ -845,8 +819,6 @@ test "enum with one member and custom tag type" { } test "enum with one member and u1 tag type @enumToInt" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const Enum = enum(u1) { Test, }; @@ -854,8 +826,6 @@ test "enum with one member and u1 tag type @enumToInt" { } test "enum with comptime_int tag type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const Enum = enum(comptime_int) { One = 3, Two = 2, @@ -865,8 +835,6 @@ test "enum with comptime_int tag type" { } test "enum with one member default to u0 tag type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const E0 = enum { X }; comptime try expect(Tag(E0) == u0); } @@ -883,15 +851,11 @@ fn doALoopThing(id: EnumWithOneMember) void { } test "comparison operator on enum with one member is comptime known" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - doALoopThing(EnumWithOneMember.Eof); } const State = enum { Start }; test "switch on enum with one member is comptime known" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var state = State.Start; switch (state) { State.Start => return, @@ -900,8 +864,6 @@ test "switch on enum with one member is comptime known" { } test "method call on an enum" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const S = struct { const E = enum { one, @@ -1141,8 +1103,6 @@ fn getC(data: *const BitFieldOfEnums) C { } test "enum literal in array literal" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const Items = enum { one, two }; const array = [_]Items{ .one, .two }; diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 982926c5bf..61d192b483 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -6,16 +6,12 @@ const expectEqual = std.testing.expectEqual; const mem = std.mem; test "error values" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const a = @errorToInt(error.err1); const b = @errorToInt(error.err2); try expect(a != b); } test "redefinition of error values allowed" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - shouldBeNotEqual(error.AnError, error.SecondError); } fn shouldBeNotEqual(a: anyerror, b: anyerror) void { @@ -36,8 +32,6 @@ fn errBinaryOperatorG(x: bool) anyerror!isize { } test "empty error union" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const x = error{} || error{}; _ = x; } @@ -91,8 +85,6 @@ fn makeANonErr() anyerror!i32 { } test "syntax: optional operator in front of error union operator" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - comptime { try expect(?(anyerror!i32) == ?(anyerror!i32)); } @@ -147,8 +139,6 @@ test "implicit cast to optional to error union to return result loc" { } test "error: fn returning empty error set can be passed as fn returning any error" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - entry(); comptime entry(); } @@ -165,7 +155,6 @@ fn foo2(f: fn () anyerror!void) void { fn bar2() (error{}!void) {} test "error union type " { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO @@ -182,7 +171,6 @@ fn testErrorUnionType() !void { } test "error set type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO @@ -209,7 +197,6 @@ fn testErrorSetType() !void { } test "explicit error set cast" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO diff --git a/test/behavior/floatop.zig b/test/behavior/floatop.zig index 9f8636ad6e..11c15e7612 100644 --- a/test/behavior/floatop.zig +++ b/test/behavior/floatop.zig @@ -24,7 +24,6 @@ test "floating point comparisons" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try testFloatComparisons(); comptime try testFloatComparisons(); @@ -96,7 +95,6 @@ test "negative f128 floatToInt at compile-time" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const a: f128 = -2; var b = @floatToInt(i64, a); diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index b3a32fe9d9..2038fd12e4 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -5,8 +5,6 @@ const expect = testing.expect; const expectEqual = testing.expectEqual; test "params" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try expect(testParamsAdd(22, 11) == 33); } fn testParamsAdd(a: i32, b: i32) i32 { @@ -14,8 +12,6 @@ fn testParamsAdd(a: i32, b: i32) i32 { } test "local variables" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - testLocVars(2); } fn testLocVars(b: i32) void { @@ -24,8 +20,6 @@ fn testLocVars(b: i32) void { } test "mutable local variables" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var zero: i32 = 0; try expect(zero == 0); @@ -37,8 +31,6 @@ test "mutable local variables" { } test "separate block scopes" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - { const no_conflict: i32 = 5; try expect(no_conflict == 5); @@ -55,14 +47,10 @@ fn @"weird function name"() i32 { return 1234; } test "weird function name" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try expect(@"weird function name"() == 1234); } test "assign inline fn to const variable" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const a = inlineFn; a(); } @@ -80,8 +68,6 @@ fn outer(y: u32) *const fn (u32) u32 { } test "return inner function which references comptime variable of outer function" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage1) return error.SkipZigTest; var func = outer(10); @@ -149,8 +135,6 @@ test "inline function call that calls optional function pointer, return pointer } test "implicit cast function unreachable return" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - wantsFnWithVoid(fnWithUnreachable); } @@ -348,8 +332,6 @@ fn fn4() u32 { } test "number literal as an argument" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try numberLiteralArg(3); comptime try numberLiteralArg(3); } @@ -380,8 +362,6 @@ test "function call with anon list literal" { } test "ability to give comptime types and non comptime types to same parameter" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const S = struct { fn doTheTest() !void { var x: i32 = 1; diff --git a/test/behavior/for.zig b/test/behavior/for.zig index 023a2d3c30..c35d0b9b1c 100644 --- a/test/behavior/for.zig +++ b/test/behavior/for.zig @@ -21,8 +21,6 @@ test "continue in for loop" { } test "break from outer for loop" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try testBreakOuter(); comptime try testBreakOuter(); } @@ -40,8 +38,6 @@ fn testBreakOuter() !void { } test "continue outer for loop" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try testContinueOuter(); comptime try testContinueOuter(); } @@ -59,8 +55,6 @@ fn testContinueOuter() !void { } test "ignore lval with underscore (for loop)" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - for ([_]void{}) |_, i| { _ = i; for ([_]void{}) |_, j| { diff --git a/test/behavior/generics.zig b/test/behavior/generics.zig index c73ae26e28..016ab8575b 100644 --- a/test/behavior/generics.zig +++ b/test/behavior/generics.zig @@ -5,8 +5,6 @@ const expect = testing.expect; const expectEqual = testing.expectEqual; test "one param, explicit comptime" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var x: usize = 0; x += checkSize(i32); x += checkSize(bool); @@ -42,8 +40,6 @@ fn add(comptime a: i32, b: i32) i32 { const the_max = max(u32, 1234, 5678); test "compile time generic eval" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try expect(the_max == 5678); } @@ -142,8 +138,6 @@ pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) type { } test "const decls in struct" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try expect(GenericDataThing(3).count_plus_one == 4); } fn GenericDataThing(comptime count: isize) type { @@ -153,8 +147,6 @@ fn GenericDataThing(comptime count: isize) type { } test "use generic param in generic param" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try expect(aGenericFn(i32, 3, 4) == 7); } fn aGenericFn(comptime T: type, comptime a: T, b: T) T { @@ -197,7 +189,6 @@ test "generic fn keeps non-generic parameter types" { } test "array of generic fns" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; try expect(foos[0](true)); diff --git a/test/behavior/if.zig b/test/behavior/if.zig index 349d7d233d..2f5a52f7e2 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -4,8 +4,6 @@ const expect = std.testing.expect; const expectEqual = std.testing.expectEqual; test "if statements" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - shouldBeEqual(1, 1); firstEqlThird(2, 1, 2); } @@ -29,8 +27,6 @@ fn firstEqlThird(a: i32, b: i32, c: i32) void { } test "else if expression" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try expect(elseIfExpressionF(1) == 1); } fn elseIfExpressionF(c: u8) u8 { @@ -64,8 +60,6 @@ test "unwrap mutable global var" { } test "labeled break inside comptime if inside runtime if" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var answer: i32 = 0; var c = true; if (c) { @@ -77,8 +71,6 @@ test "labeled break inside comptime if inside runtime if" { } test "const result loc, runtime if cond, else unreachable" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const Num = enum { One, Two }; var t = true; diff --git a/test/behavior/inttoptr.zig b/test/behavior/inttoptr.zig index f559f9776b..d5f4503b03 100644 --- a/test/behavior/inttoptr.zig +++ b/test/behavior/inttoptr.zig @@ -2,7 +2,6 @@ const builtin = @import("builtin"); test "casting integer address to function pointer" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; addressToFunction(); comptime addressToFunction(); diff --git a/test/behavior/math.zig b/test/behavior/math.zig index c541ab4731..dcb713392a 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -312,7 +312,6 @@ test "comptime_int multi-limb partial shift right" { test "xor" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try test_xor(); comptime try test_xor(); @@ -732,7 +731,6 @@ test "overflow arithmetic with u0 values" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO var result: u0 = undefined; try expect(!@addWithOverflow(u0, 0, 0, &result)); diff --git a/test/behavior/null.zig b/test/behavior/null.zig index 43c9355f3c..01611eaef8 100644 --- a/test/behavior/null.zig +++ b/test/behavior/null.zig @@ -125,8 +125,6 @@ fn baz(x: ?Empty) ?Empty { } test "null with default unwrap" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const x: i32 = null orelse 1; try expect(x == 1); } diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index a00297f84b..edb14e7f61 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -218,8 +218,6 @@ test "compile time slice of pointer to hard coded address" { } test "slice string literal has correct type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - comptime { try expect(@TypeOf("aoeu"[0..]) == *const [4:0]u8); const array = [_]i32{ 1, 2, 3, 4 }; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index fdf6da15a8..32e374d3d5 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -213,8 +213,6 @@ fn makeBar2(x: i32, y: i32) Bar { } test "call method with mutable reference to struct with no fields" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const S = struct { fn doC(s: *const @This()) bool { _ = s; @@ -768,7 +766,6 @@ test "pointer to packed struct member in a stack variable" { test "packed struct with u0 field access" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO const S = packed struct { diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index fab564f71d..659202361b 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -190,8 +190,6 @@ test "switch with disjoint range" { } test "switch variable for range and multiple prongs" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - const S = struct { fn doTheTest() !void { var u: u8 = 16; @@ -357,8 +355,6 @@ fn returnsFalse() bool { } } test "switch on const enum with var" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - try expect(!returnsFalse()); } diff --git a/test/behavior/this.zig b/test/behavior/this.zig index a284310b1a..71a083d2f0 100644 --- a/test/behavior/this.zig +++ b/test/behavior/this.zig @@ -21,8 +21,6 @@ fn add(x: i32, y: i32) i32 { } test "this refer to module call private fn" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try expect(module.add(1, 2) == 3); } diff --git a/test/behavior/truncate.zig b/test/behavior/truncate.zig index 26205d56b6..7a0213499e 100644 --- a/test/behavior/truncate.zig +++ b/test/behavior/truncate.zig @@ -3,62 +3,46 @@ const builtin = @import("builtin"); const expect = std.testing.expect; test "truncate u0 to larger integer allowed and has comptime known result" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var x: u0 = 0; const y = @truncate(u8, x); comptime try expect(y == 0); } test "truncate.u0.literal" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var z = @truncate(u0, 0); try expect(z == 0); } test "truncate.u0.const" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const c0: usize = 0; var z = @truncate(u0, c0); try expect(z == 0); } test "truncate.u0.var" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var d: u8 = 2; var z = @truncate(u0, d); try expect(z == 0); } test "truncate i0 to larger integer allowed and has comptime known result" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var x: i0 = 0; const y = @truncate(i8, x); comptime try expect(y == 0); } test "truncate.i0.literal" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var z = @truncate(i0, 0); try expect(z == 0); } test "truncate.i0.const" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const c0: isize = 0; var z = @truncate(i0, c0); try expect(z == 0); } test "truncate.i0.var" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var d: i8 = 2; var z = @truncate(i0, d); try expect(z == 0); diff --git a/test/behavior/try.zig b/test/behavior/try.zig index f2a836e182..b0559d4549 100644 --- a/test/behavior/try.zig +++ b/test/behavior/try.zig @@ -24,8 +24,6 @@ fn returnsTen() anyerror!i32 { } test "try without vars" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const result1 = if (failIfTrue(true)) 1 else |_| @as(i32, 2); try expect(result1 == 2); @@ -42,8 +40,6 @@ fn failIfTrue(ok: bool) anyerror!void { } test "try then not executed with assignment" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (failIfTrue(true)) { unreachable; } else |err| { diff --git a/test/behavior/usingnamespace.zig b/test/behavior/usingnamespace.zig index 8caf2af27c..987fc95e24 100644 --- a/test/behavior/usingnamespace.zig +++ b/test/behavior/usingnamespace.zig @@ -11,8 +11,6 @@ const C = struct { }; test "basic usingnamespace" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try std.testing.expect(C.B == bool); } @@ -23,8 +21,6 @@ fn Foo(comptime T: type) type { } test "usingnamespace inside a generic struct" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const std2 = Foo(std); const testing2 = Foo(std.testing); try std2.testing.expect(true); @@ -36,8 +32,6 @@ usingnamespace struct { }; test "usingnamespace does not redeclare an imported variable" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - comptime try std.testing.expect(@This().foo == 42); } @@ -54,8 +48,6 @@ fn privateFunction() bool { } test { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - _ = @import("usingnamespace/import_segregation.zig"); } diff --git a/test/behavior/while.zig b/test/behavior/while.zig index c1f41e5677..d49507c7df 100644 --- a/test/behavior/while.zig +++ b/test/behavior/while.zig @@ -247,8 +247,6 @@ fn returnTrue() bool { } test "return with implicit cast from while loop" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - returnWithImplicitCastFromWhileLoopTest() catch unreachable; } fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { -- cgit v1.2.3 From 3ea603c82a3b7b5d45f21e35d8ce9f6029ff6c3a Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Mon, 7 Mar 2022 19:33:58 +0100 Subject: stage2 ARM: implement ptr_add, ptr_sub for all element sizes Also reduces slice_elem_val to ptr_add, simplifying the implementation --- src/arch/arm/CodeGen.zig | 100 ++++++++++++++++------------------------------- test/behavior/align.zig | 1 - test/behavior/array.zig | 1 - test/behavior/cast.zig | 1 - 4 files changed, 34 insertions(+), 69 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 5a45019224..c4220d23f4 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -1434,29 +1434,11 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { break :result dst_mcv; }, else => { - const dst_mcv = try self.allocRegOrMem(inst, true); + const dest = try self.allocRegOrMem(inst, true); + const addr = try self.binOp(.ptr_add, null, base_mcv, index_mcv, slice_ty, Type.usize); + try self.load(dest, addr, slice_ptr_field_type); - const offset_mcv = try self.binOp( - .mul, - null, - index_mcv, - .{ .immediate = elem_size }, - Type.usize, - Type.usize, - ); - assert(offset_mcv == .register); // result of multiplication should always be register - self.register_manager.freezeRegs(&.{offset_mcv.register}); - - const addr_mcv = try self.binOp(.add, null, base_mcv, offset_mcv, Type.usize, Type.usize); - - // At this point in time, neither the base register - // nor the offset register contains any valuable data - // anymore. - self.register_manager.unfreezeRegs(&.{ base_mcv.register, offset_mcv.register }); - - try self.load(dst_mcv, addr_mcv, slice_ptr_field_type); - - break :result dst_mcv; + break :result dest; }, } }; @@ -1710,6 +1692,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type defer self.register_manager.unfreezeRegs(&.{addr_reg}); switch (value) { + .dead => unreachable, + .undef => unreachable, .register => |value_reg| { try self.genStrRegister(value_reg, addr_reg, value_ty); }, @@ -2140,7 +2124,7 @@ fn binOp( rhs: MCValue, lhs_ty: Type, rhs_ty: Type, -) !MCValue { +) InnerError!MCValue { switch (tag) { .add, .sub, @@ -2281,16 +2265,21 @@ fn binOp( switch (lhs_ty.zigTypeTag()) { .Pointer => { const ptr_ty = lhs_ty; - const pointee_ty = switch (ptr_ty.ptrSize()) { + const elem_ty = switch (ptr_ty.ptrSize()) { .One => ptr_ty.childType().childType(), // ptr to array, so get array element type else => ptr_ty.childType(), }; + const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*)); - if (pointee_ty.abiSize(self.target.*) > 1) { - return self.fail("TODO ptr_add, ptr_sub with more element sizes", .{}); + if (elem_size == 1) { + return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); + } else { + // convert the offset into a byte offset by + // multiplying it with elem_size + const offset = try self.binOp(.mul, null, rhs, .{ .immediate = elem_size }, Type.usize, Type.usize); + const addr = try self.binOp(tag, null, lhs, offset, Type.initTag(.manyptr_u8), Type.usize); + return addr; } - - return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); }, else => unreachable, } @@ -3494,6 +3483,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro const reg = try self.copyToTmpRegister(ty, mcv); return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); } else { + var ptr_ty_payload: Type.Payload.ElemType = .{ + .base = .{ .tag = .single_mut_pointer }, + .data = ty, + }; + const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + // TODO call extern memcpy const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }); const src_reg = regs[0]; @@ -3505,20 +3500,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro switch (mcv) { .stack_offset => |off| { // sub src_reg, fp, #off - const adj_src_offset = off + @intCast(u32, abi_size); - const src_offset_op: Instruction.Operand = if (Instruction.Operand.fromU32(adj_src_offset)) |x| x else { - return self.fail("TODO load: set reg to stack offset with all possible offsets", .{}); - }; - _ = try self.addInst(.{ - .tag = .sub, - .data = .{ .rr_op = .{ - .rd = src_reg, - .rn = .fp, - .op = src_offset_op, - } }, - }); + try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off }); }, - .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = @intCast(u32, addr) }), + .memory => |addr| try self.genSetReg(ptr_ty, src_reg, .{ .immediate = @intCast(u32, addr) }), .embedded_in_code, .stack_argument_offset, => return self.fail("TODO genSetStack with src={}", .{mcv}), @@ -3526,18 +3510,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro } // sub dst_reg, fp, #stack_offset - const adj_dst_offset = stack_offset + abi_size; - const dst_offset_op: Instruction.Operand = if (Instruction.Operand.fromU32(adj_dst_offset)) |x| x else { - return self.fail("TODO load: set reg to stack offset with all possible offsets", .{}); - }; - _ = try self.addInst(.{ - .tag = .sub, - .data = .{ .rr_op = .{ - .rd = dst_reg, - .rn = .fp, - .op = dst_offset_op, - } }, - }); + try self.genSetReg(ptr_ty, dst_reg, .{ .ptr_stack_offset = stack_offset }); // mov len, #abi_size try self.genSetReg(Type.usize, len_reg, .{ .immediate = abi_size }); @@ -3882,6 +3855,12 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I const reg = try self.copyToTmpRegister(ty, mcv); return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg }); } else { + var ptr_ty_payload: Type.Payload.ElemType = .{ + .base = .{ .tag = .single_mut_pointer }, + .data = ty, + }; + const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + // TODO call extern memcpy const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }); const src_reg = regs[0]; @@ -3893,20 +3872,9 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I switch (mcv) { .stack_offset => |off| { // sub src_reg, fp, #off - const adj_src_offset = off + abi_size; - const src_offset_op: Instruction.Operand = if (Instruction.Operand.fromU32(adj_src_offset)) |x| x else { - return self.fail("TODO load: set reg to stack offset with all possible offsets", .{}); - }; - _ = try self.addInst(.{ - .tag = .sub, - .data = .{ .rr_op = .{ - .rd = src_reg, - .rn = .fp, - .op = src_offset_op, - } }, - }); + try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off }); }, - .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = @intCast(u32, addr) }), + .memory => |addr| try self.genSetReg(ptr_ty, src_reg, .{ .immediate = @intCast(u32, addr) }), .stack_argument_offset, .embedded_in_code, => return self.fail("TODO genSetStackArgument src={}", .{mcv}), diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 429169a3fe..e4c497984c 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -105,7 +105,6 @@ fn fnWithAlignedStack() i32 { test "implicitly decreasing slice alignment" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const a: u32 align(4) = 3; const b: u32 align(8) = 4; diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 6482c1db2d..e6204729d4 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -8,7 +8,6 @@ const expectEqual = testing.expectEqual; test "array to slice" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const a: u32 align(4) = 3; const b: u32 align(8) = 4; diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index a3138ff88a..aa037127ad 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -984,7 +984,6 @@ test "peer type resolve array pointers, one of them const" { test "peer type resolve array pointer and unknown pointer" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO const const_array: [4]u8 = undefined; -- cgit v1.2.3 From f736cde397a6abb1399827ed5988c43001706580 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 9 Mar 2022 18:47:42 -0700 Subject: Sema: implement pointer to tuple to pointer to array coercion This involved an LLVM backend fix for the aggregate_init instruction. --- src/Sema.zig | 62 ++++++++++++++++++++++++++++++++++-------------- src/codegen/llvm.zig | 21 ++++++++++++---- test/behavior/align.zig | 10 ++++---- test/behavior/array.zig | 5 ++-- test/behavior/basic.zig | 3 ++- test/behavior/slice.zig | 10 ++++---- test/behavior/struct.zig | 2 +- test/behavior/while.zig | 8 +++---- 8 files changed, 80 insertions(+), 41 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/Sema.zig b/src/Sema.zig index 64d6e1b373..11f250e44c 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -16005,9 +16005,17 @@ fn coerce( return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); } - // coercion to C pointer - if (dest_info.size == .C) { - switch (inst_ty.zigTypeTag()) { + // cast from *T and [*]T to *anyopaque + // but don't do it if the source type is a double pointer + if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer and + inst_ty.childType().zigTypeTag() != .Pointer) + { + return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); + } + + switch (dest_info.size) { + // coercion to C pointer + .C => switch (inst_ty.zigTypeTag()) { .Null => { return sema.addConstant(dest_ty, Value.@"null"); }, @@ -16041,22 +16049,10 @@ fn coerce( return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); }, else => {}, - } - } - - // cast from *T and [*]T to *anyopaque - // but don't do it if the source type is a double pointer - if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer and - inst_ty.childType().zigTypeTag() != .Pointer) - { - return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); - } - - switch (dest_info.size) { - .C, .Many => {}, + }, .One => switch (dest_info.pointee_type.zigTypeTag()) { .Union => { - // cast from pointer to anonymous struct to pointer to union + // pointer to anonymous struct to pointer to union if (inst_ty.isSinglePointer() and inst_ty.childType().isAnonStruct() and !dest_info.mutable) @@ -16065,7 +16061,7 @@ fn coerce( } }, .Struct => { - // cast from pointer to anonymous struct to pointer to struct + // pointer to anonymous struct to pointer to struct if (inst_ty.isSinglePointer() and inst_ty.childType().isAnonStruct() and !dest_info.mutable) @@ -16073,6 +16069,15 @@ fn coerce( return sema.coerceAnonStructToStructPtrs(block, dest_ty, dest_ty_src, inst, inst_src); } }, + .Array => { + // pointer to tuple to pointer to array + if (inst_ty.isSinglePointer() and + inst_ty.childType().isTuple() and + !dest_info.mutable) + { + return sema.coerceTupleToArrayPtrs(block, dest_ty, dest_ty_src, inst, inst_src); + } + }, else => {}, }, .Slice => { @@ -16084,6 +16089,7 @@ fn coerce( return sema.coerceTupleToSlicePtrs(block, dest_ty, dest_ty_src, inst, inst_src); } }, + .Many => {}, } // This will give an extra hint on top of what the bottom of this func would provide. @@ -17554,6 +17560,26 @@ fn coerceTupleToSlicePtrs( return sema.coerceArrayPtrToSlice(block, slice_ty, ptr_array, slice_ty_src); } +/// If the lengths match, coerces element-wise. +fn coerceTupleToArrayPtrs( + sema: *Sema, + block: *Block, + ptr_array_ty: Type, + array_ty_src: LazySrcLoc, + ptr_tuple: Air.Inst.Ref, + tuple_src: LazySrcLoc, +) !Air.Inst.Ref { + const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); + const ptr_info = ptr_array_ty.ptrInfo().data; + const array_ty = ptr_info.pointee_type; + const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src); + if (ptr_info.@"align" != 0) { + return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{}); + } + const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst); + return ptr_array; +} + /// Handles both tuples and anon struct literals. Coerces field-wise. Reports /// errors for both extra fields and missing fields. fn coerceTupleToStruct( diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index fb7daa80ec..aacb3af47d 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -5838,8 +5838,15 @@ pub const FuncGen = struct { const llvm_i = llvmFieldIndex(result_ty, i, target, &ptr_ty_buf).?; indices[1] = llvm_u32.constInt(llvm_i, .False); const field_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, ""); - const store_inst = self.builder.buildStore(llvm_elem, field_ptr); - store_inst.setAlignment(result_ty.structFieldAlign(i, target)); + var field_ptr_payload: Type.Payload.Pointer = .{ + .data = .{ + .pointee_type = self.air.typeOf(elem), + .@"align" = result_ty.structFieldAlign(i, target), + .@"addrspace" = .generic, + }, + }; + const field_ptr_ty = Type.initPayload(&field_ptr_payload.base); + self.store(field_ptr, field_ptr_ty, llvm_elem, .NotAtomic); } return alloca_inst; @@ -5871,8 +5878,14 @@ pub const FuncGen = struct { }; const elem_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, ""); const llvm_elem = try self.resolveInst(elem); - const store_inst = self.builder.buildStore(llvm_elem, elem_ptr); - store_inst.setAlignment(elem_ty.abiAlignment(target)); + var elem_ptr_payload: Type.Payload.Pointer = .{ + .data = .{ + .pointee_type = elem_ty, + .@"addrspace" = .generic, + }, + }; + const elem_ptr_ty = Type.initPayload(&elem_ptr_payload.base); + self.store(elem_ptr, elem_ptr_ty, llvm_elem, .NotAtomic); } return alloca_inst; diff --git a/test/behavior/align.zig b/test/behavior/align.zig index c9a43526f6..50ba13073d 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -193,11 +193,9 @@ test "function alignment" { } test "implicitly decreasing fn alignment" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // function alignment is a compile error on wasm32/wasm64 @@ -321,7 +319,6 @@ const DefaultAligned = struct { test "read 128-bit field from default aligned struct in stack memory" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -353,10 +350,10 @@ test "read 128-bit field from default aligned struct in global memory" { test "struct field explicit alignment" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const S = struct { const Node = struct { @@ -402,8 +399,9 @@ test "align(@alignOf(T)) T does not force resolution of T" { } test "align(N) on functions" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage1) return error.SkipZigTest; + + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; diff --git a/test/behavior/array.zig b/test/behavior/array.zig index e6204729d4..efd6624445 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -553,12 +553,11 @@ test "type coercion of anon struct literal to array" { } test "type coercion of pointer to anon struct literal to pointer to array" { - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { const U = union { diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index 25a302398b..481a15bbe5 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -760,7 +760,8 @@ test "pointer to thread local array" { threadlocal var buffer: [11]u8 = undefined; test "auto created variables have correct alignment" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { fn foo(str: [*]const u8) u32 { diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index f5421f9159..09025df69f 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -518,7 +518,11 @@ test "slice syntax resulting in pointer-to-array" { } test "type coercion of pointer to anon struct literal to pointer to slice" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { const U = union { @@ -546,7 +550,7 @@ test "type coercion of pointer to anon struct literal to pointer to slice" { try expect(mem.eql(u8, slice2[2], "world!")); } }; - // try S.doTheTest(); + try S.doTheTest(); comptime try S.doTheTest(); } @@ -578,8 +582,6 @@ test "slice bounds in comptime concatenation" { } test "slice sentinel access at comptime" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - { const str0 = &[_:0]u8{ '1', '2', '3' }; const slice0: [:0]const u8 = str0; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 02bfd2fa5b..6e48f7ca21 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -426,7 +426,7 @@ test "packed struct 24bits" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_llvm and builtin.stage2_arch == .wasm32) return error.SkipZigTest; // TODO + if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO comptime { try expect(@sizeOf(Foo24Bits) == 4); diff --git a/test/behavior/while.zig b/test/behavior/while.zig index dced1ee208..a5b777640a 100644 --- a/test/behavior/while.zig +++ b/test/behavior/while.zig @@ -289,9 +289,8 @@ test "while bool 2 break statements and an else" { } test "while optional 2 break statements and an else" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { fn entry(opt_t: ?bool, f: bool) !void { @@ -308,7 +307,8 @@ test "while optional 2 break statements and an else" { } test "while error 2 break statements and an else" { - if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { fn entry(opt_t: anyerror!bool, f: bool) !void { -- cgit v1.2.3 From 797f4db227dcdbe48ffb309763a48fbe6eaf5935 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 11 Mar 2022 09:36:57 -0800 Subject: stage2: Array len field should be a usize not comptime_int --- src/Sema.zig | 6 +++--- test/behavior/array.zig | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/Sema.zig b/src/Sema.zig index ac43ef76b3..00553710df 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -14948,7 +14948,7 @@ fn fieldVal( .Array => { if (mem.eql(u8, field_name, "len")) { return sema.addConstant( - Type.comptime_int, + Type.usize, try Value.Tag.int_u64.create(arena, inner_ty.arrayLen()), ); } else { @@ -14986,7 +14986,7 @@ fn fieldVal( } else if (ptr_info.pointee_type.zigTypeTag() == .Array) { if (mem.eql(u8, field_name, "len")) { return sema.addConstant( - Type.comptime_int, + Type.usize, try Value.Tag.int_u64.create(arena, ptr_info.pointee_type.arrayLen()), ); } else { @@ -15131,7 +15131,7 @@ fn fieldPtr( var anon_decl = try block.startAnonDecl(src); defer anon_decl.deinit(); return sema.analyzeDeclRef(try anon_decl.finish( - Type.initTag(.comptime_int), + Type.usize, try Value.Tag.int_u64.create(anon_decl.arena(), inner_ty.arrayLen()), )); } else { diff --git a/test/behavior/array.zig b/test/behavior/array.zig index efd6624445..eb8ae8972d 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -104,6 +104,7 @@ test "array len field" { comptime try expect(arr.len == 4); try expect(ptr.len == 4); comptime try expect(ptr.len == 4); + try expect(@TypeOf(arr.len) == usize); } test "array with sentinels" { -- cgit v1.2.3 From 55ba335e0ffc2af76bf0743d98f5a959ccce0409 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 11 Mar 2022 19:31:29 -0700 Subject: Sema: fix resolution of inferred error sets Introduce `Module.ensureFuncBodyAnalyzed` and corresponding `Sema` function. This mirrors `ensureDeclAnalyzed` except also waits until the function body has been semantically analyzed, meaning that inferred error sets will have been populated. Resolving error sets can now emit a "unable to resolve inferred error set" error instead of producing an incorrect error set type. Resolving error sets now calls `ensureFuncBodyAnalyzed`. Closes #11046. `coerceInMemoryAllowedErrorSets` now does a lot more work to avoid resolving an inferred error set if possible. Same with `wrapErrorUnionSet`. Inferred error set types no longer check the `func` field to determine if they are equal. That was incorrect because an inline or comptime function call produces a unique error set which has the same `*Module.Fn` value for this field. Instead we use the `*Module.Fn.InferredErrorSet` pointers to test equality of inferred error sets. --- src/Compilation.zig | 134 +++++++--------------------------- src/Module.zig | 121 ++++++++++++++++++++++++++---- src/Sema.zig | 170 ++++++++++++++++++++++++++----------------- src/type.zig | 10 +-- test/behavior.zig | 1 + test/behavior/array.zig | 3 - test/behavior/bugs/11046.zig | 21 ++++++ test/behavior/error.zig | 6 +- 8 files changed, 271 insertions(+), 195 deletions(-) create mode 100644 test/behavior/bugs/11046.zig (limited to 'test/behavior/array.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index fa2e4ca68b..5e02d8dba2 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -15,7 +15,6 @@ const Package = @import("Package.zig"); const link = @import("link.zig"); const tracy = @import("tracy.zig"); const trace = tracy.trace; -const Liveness = @import("Liveness.zig"); const build_options = @import("build_options"); const LibCInstallation = @import("libc_installation.zig").LibCInstallation; const glibc = @import("glibc.zig"); @@ -2702,12 +2701,12 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress => return, .complete, .codegen_failure_retryable => { - const named_frame = tracy.namedFrame("codegen_decl"); - defer named_frame.end(); - if (build_options.omit_stage2) @panic("sadly stage2 is omitted from this build to save memory on the CI server"); + const named_frame = tracy.namedFrame("codegen_decl"); + defer named_frame.end(); + const module = comp.bin_file.options.module.?; assert(decl.has_tv); @@ -2722,100 +2721,18 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress return; }, }, - .codegen_func => |func| switch (func.owner_decl.analysis) { - .unreferenced => unreachable, - .in_progress => unreachable, - .outdated => unreachable, - - .file_failure, - .sema_failure, - .codegen_failure, - .dependency_failure, - .sema_failure_retryable, - => return, - - .complete, .codegen_failure_retryable => { - if (build_options.omit_stage2) - @panic("sadly stage2 is omitted from this build to save memory on the CI server"); - switch (func.state) { - .sema_failure, .dependency_failure => return, - .queued => {}, - .in_progress => unreachable, - .inline_only => unreachable, // don't queue work for this - .success => unreachable, // don't queue it twice - } - - const gpa = comp.gpa; - const module = comp.bin_file.options.module.?; - const decl = func.owner_decl; - - var tmp_arena = std.heap.ArenaAllocator.init(gpa); - defer tmp_arena.deinit(); - const sema_arena = tmp_arena.allocator(); - - const sema_frame = tracy.namedFrame("sema"); - var sema_frame_ended = false; - errdefer if (!sema_frame_ended) sema_frame.end(); - - var air = module.analyzeFnBody(decl, func, sema_arena) catch |err| switch (err) { - error.AnalysisFail => { - if (func.state == .in_progress) { - // If this decl caused the compile error, the analysis field would - // be changed to indicate it was this Decl's fault. Because this - // did not happen, we infer here that it was a dependency failure. - func.state = .dependency_failure; - } - return; - }, - error.OutOfMemory => return error.OutOfMemory, - }; - defer air.deinit(gpa); - - sema_frame.end(); - sema_frame_ended = true; - - if (comp.bin_file.options.emit == null) return; - - const liveness_frame = tracy.namedFrame("liveness"); - var liveness_frame_ended = false; - errdefer if (!liveness_frame_ended) liveness_frame.end(); - - log.debug("analyze liveness of {s}", .{decl.name}); - var liveness = try Liveness.analyze(gpa, air); - defer liveness.deinit(gpa); - - liveness_frame.end(); - liveness_frame_ended = true; - - if (builtin.mode == .Debug and comp.verbose_air) { - std.debug.print("# Begin Function AIR: {s}:\n", .{decl.name}); - @import("print_air.zig").dump(gpa, air, liveness); - std.debug.print("# End Function AIR: {s}\n\n", .{decl.name}); - } + .codegen_func => |func| { + if (build_options.omit_stage2) + @panic("sadly stage2 is omitted from this build to save memory on the CI server"); - const named_frame = tracy.namedFrame("codegen"); - defer named_frame.end(); + const named_frame = tracy.namedFrame("codegen_func"); + defer named_frame.end(); - comp.bin_file.updateFunc(module, func, air, liveness) catch |err| switch (err) { - error.OutOfMemory => return error.OutOfMemory, - error.AnalysisFail => { - decl.analysis = .codegen_failure; - return; - }, - else => { - try module.failed_decls.ensureUnusedCapacity(gpa, 1); - module.failed_decls.putAssumeCapacityNoClobber(decl, try Module.ErrorMsg.create( - gpa, - decl.srcLoc(), - "unable to codegen: {s}", - .{@errorName(err)}, - )); - decl.analysis = .codegen_failure_retryable; - return; - }, - }; - return; - }, + const module = comp.bin_file.options.module.?; + module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => return, + }; }, .emit_h_decl => |decl| switch (decl.analysis) { .unreferenced => unreachable, @@ -2831,11 +2748,12 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress // emit-h only requires semantic analysis of the Decl to be complete, // it does not depend on machine code generation to succeed. .codegen_failure, .codegen_failure_retryable, .complete => { + if (build_options.omit_stage2) + @panic("sadly stage2 is omitted from this build to save memory on the CI server"); + const named_frame = tracy.namedFrame("emit_h_decl"); defer named_frame.end(); - if (build_options.omit_stage2) - @panic("sadly stage2 is omitted from this build to save memory on the CI server"); const gpa = comp.gpa; const module = comp.bin_file.options.module.?; const emit_h = module.emit_h.?; @@ -2871,11 +2789,12 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress }, }, .analyze_decl => |decl| { + if (build_options.omit_stage2) + @panic("sadly stage2 is omitted from this build to save memory on the CI server"); + const named_frame = tracy.namedFrame("analyze_decl"); defer named_frame.end(); - if (build_options.omit_stage2) - @panic("sadly stage2 is omitted from this build to save memory on the CI server"); const module = comp.bin_file.options.module.?; module.ensureDeclAnalyzed(decl) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, @@ -2883,11 +2802,12 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress }; }, .update_embed_file => |embed_file| { + if (build_options.omit_stage2) + @panic("sadly stage2 is omitted from this build to save memory on the CI server"); + const named_frame = tracy.namedFrame("update_embed_file"); defer named_frame.end(); - if (build_options.omit_stage2) - @panic("sadly stage2 is omitted from this build to save memory on the CI server"); const module = comp.bin_file.options.module.?; module.updateEmbedFile(embed_file) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, @@ -2895,11 +2815,12 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress }; }, .update_line_number => |decl| { + if (build_options.omit_stage2) + @panic("sadly stage2 is omitted from this build to save memory on the CI server"); + const named_frame = tracy.namedFrame("update_line_number"); defer named_frame.end(); - if (build_options.omit_stage2) - @panic("sadly stage2 is omitted from this build to save memory on the CI server"); const gpa = comp.gpa; const module = comp.bin_file.options.module.?; comp.bin_file.updateDeclLineNumber(module, decl) catch |err| { @@ -2914,11 +2835,12 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress }; }, .analyze_pkg => |pkg| { + if (build_options.omit_stage2) + @panic("sadly stage2 is omitted from this build to save memory on the CI server"); + const named_frame = tracy.namedFrame("analyze_pkg"); defer named_frame.end(); - if (build_options.omit_stage2) - @panic("sadly stage2 is omitted from this build to save memory on the CI server"); const module = comp.bin_file.options.module.?; module.semaPkg(pkg) catch |err| switch (err) { error.CurrentWorkingDirectoryUnlinked, diff --git a/src/Module.zig b/src/Module.zig index 693cc3b5a0..b3e0344d77 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -3,6 +3,7 @@ //! there is or is not any zig source code, respectively. const std = @import("std"); +const builtin = @import("builtin"); const mem = std.mem; const Allocator = std.mem.Allocator; const ArrayListUnmanaged = std.ArrayListUnmanaged; @@ -28,6 +29,7 @@ const AstGen = @import("AstGen.zig"); const Sema = @import("Sema.zig"); const target_util = @import("target.zig"); const build_options = @import("build_options"); +const Liveness = @import("Liveness.zig"); /// General-purpose allocator. Used for both temporary and long-term storage. gpa: Allocator, @@ -1438,8 +1440,11 @@ pub const Fn = struct { is_cold: bool = false, is_noinline: bool = false, - /// Any inferred error sets that this function owns, both it's own inferred error set and - /// inferred error sets of any inline/comptime functions called. + /// Any inferred error sets that this function owns, both its own inferred error set and + /// inferred error sets of any inline/comptime functions called. Not to be confused + /// with inferred error sets of generic instantiations of this function, which are + /// *not* tracked here - they are tracked in the new `Fn` object created for the + /// instantiations. inferred_error_sets: InferredErrorSetList = .{}, pub const Analysis = enum { @@ -1457,28 +1462,29 @@ pub const Fn = struct { }; /// This struct is used to keep track of any dependencies related to functions instances - /// that return inferred error sets. Note that a function may be associated to multiple different error sets, - /// for example an inferred error set which this function returns, but also any inferred error sets - /// of called inline or comptime functions. + /// that return inferred error sets. Note that a function may be associated to + /// multiple different error sets, for example an inferred error set which + /// this function returns, but also any inferred error sets of called inline + /// or comptime functions. pub const InferredErrorSet = struct { /// The function from which this error set originates. - /// Note: may be the function itself. func: *Fn, - /// All currently known errors that this error set contains. This includes direct additions - /// via `return error.Foo;`, and possibly also errors that are returned from any dependent functions. - /// When the inferred error set is fully resolved, this map contains all the errors that the function might return. + /// All currently known errors that this error set contains. This includes + /// direct additions via `return error.Foo;`, and possibly also errors that + /// are returned from any dependent functions. When the inferred error set is + /// fully resolved, this map contains all the errors that the function might return. errors: ErrorSet.NameMap = .{}, /// Other inferred error sets which this inferred error set should include. inferred_error_sets: std.AutoHashMapUnmanaged(*InferredErrorSet, void) = .{}, - /// Whether the function returned anyerror. This is true if either of the dependent functions - /// returns anyerror. + /// Whether the function returned anyerror. This is true if either of + /// the dependent functions returns anyerror. is_anyerror: bool = false, - /// Whether this error set is already fully resolved. If true, resolving can skip resolving any dependents - /// of this inferred error set. + /// Whether this error set is already fully resolved. If true, resolving + /// can skip resolving any dependents of this inferred error set. is_resolved: bool = false, pub fn addErrorSet(self: *InferredErrorSet, gpa: Allocator, err_set_ty: Type) !void { @@ -1494,8 +1500,8 @@ pub const Fn = struct { try self.errors.put(gpa, name, {}); }, .error_set_inferred => { - const set = err_set_ty.castTag(.error_set_inferred).?.data; - try self.inferred_error_sets.put(gpa, set, {}); + const ies = err_set_ty.castTag(.error_set_inferred).?.data; + try self.inferred_error_sets.put(gpa, ies, {}); }, .error_set_merged => { const names = err_set_ty.castTag(.error_set_merged).?.data.keys(); @@ -3441,6 +3447,10 @@ pub fn mapOldZirToNew( } } +/// This ensures that the Decl will have a Type and Value populated. +/// However the resolution status of the Type may not be fully resolved. +/// For example an inferred error set is not resolved until after `analyzeFnBody`. +/// is called. pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void { const tracy = trace(@src()); defer tracy.end(); @@ -3533,6 +3543,87 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl: *Decl) SemaError!void { } } +pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void { + const tracy = trace(@src()); + defer tracy.end(); + + switch (func.owner_decl.analysis) { + .unreferenced => unreachable, + .in_progress => unreachable, + .outdated => unreachable, + + .file_failure, + .sema_failure, + .codegen_failure, + .dependency_failure, + .sema_failure_retryable, + => return error.AnalysisFail, + + .complete, .codegen_failure_retryable => { + switch (func.state) { + .sema_failure, .dependency_failure => return error.AnalysisFail, + .queued => {}, + .in_progress => unreachable, + .inline_only => unreachable, // don't queue work for this + .success => return, + } + + const gpa = mod.gpa; + const decl = func.owner_decl; + + var tmp_arena = std.heap.ArenaAllocator.init(gpa); + defer tmp_arena.deinit(); + const sema_arena = tmp_arena.allocator(); + + var air = mod.analyzeFnBody(decl, func, sema_arena) catch |err| switch (err) { + error.AnalysisFail => { + if (func.state == .in_progress) { + // If this decl caused the compile error, the analysis field would + // be changed to indicate it was this Decl's fault. Because this + // did not happen, we infer here that it was a dependency failure. + func.state = .dependency_failure; + } + return error.AnalysisFail; + }, + error.OutOfMemory => return error.OutOfMemory, + }; + defer air.deinit(gpa); + + if (mod.comp.bin_file.options.emit == null) return; + + log.debug("analyze liveness of {s}", .{decl.name}); + var liveness = try Liveness.analyze(gpa, air); + defer liveness.deinit(gpa); + + if (builtin.mode == .Debug and mod.comp.verbose_air) { + std.debug.print("# Begin Function AIR: {s}:\n", .{decl.name}); + @import("print_air.zig").dump(gpa, air, liveness); + std.debug.print("# End Function AIR: {s}\n\n", .{decl.name}); + } + + mod.comp.bin_file.updateFunc(mod, func, air, liveness) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => { + decl.analysis = .codegen_failure; + return; + }, + else => { + try mod.failed_decls.ensureUnusedCapacity(gpa, 1); + mod.failed_decls.putAssumeCapacityNoClobber(decl, try Module.ErrorMsg.create( + gpa, + decl.srcLoc(), + "unable to codegen: {s}", + .{@errorName(err)}, + )); + decl.analysis = .codegen_failure_retryable; + return; + }, + }; + return; + }, + } +} + pub fn updateEmbedFile(mod: *Module, embed_file: *EmbedFile) SemaError!void { const tracy = trace(@src()); defer tracy.end(); diff --git a/src/Sema.zig b/src/Sema.zig index 44b2f33d56..31295707de 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -5346,14 +5346,14 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr } if (lhs_ty.castTag(.error_set_inferred)) |payload| { - try sema.resolveInferredErrorSet(payload.data); + try sema.resolveInferredErrorSet(block, src, payload.data); // isAnyError might have changed from a false negative to a true positive after resolution. if (lhs_ty.isAnyError()) { return Air.Inst.Ref.anyerror_type; } } if (rhs_ty.castTag(.error_set_inferred)) |payload| { - try sema.resolveInferredErrorSet(payload.data); + try sema.resolveInferredErrorSet(block, src, payload.data); // isAnyError might have changed from a false negative to a true positive after resolution. if (rhs_ty.isAnyError()) { return Air.Inst.Ref.anyerror_type; @@ -6927,7 +6927,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError } } - try sema.resolveInferredErrorSetTy(operand_ty); + try sema.resolveInferredErrorSetTy(block, src, operand_ty); if (operand_ty.isAnyError()) { if (special_prong != .@"else") { @@ -10437,7 +10437,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai }; // If the error set is inferred it has to be resolved at this point - try sema.resolveInferredErrorSetTy(ty); + try sema.resolveInferredErrorSetTy(block, src, ty); // Build our list of Error values // Optional value is only null if anyerror @@ -12627,7 +12627,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! try sema.checkErrorSetType(block, operand_src, operand_ty); if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { - try sema.resolveInferredErrorSetTy(dest_ty); + try sema.resolveInferredErrorSetTy(block, src, dest_ty); if (!dest_ty.isAnyError()) { const error_name = val.castTag(.@"error").?.data.name; @@ -16616,7 +16616,7 @@ fn coerceInMemoryAllowed( // Error Sets if (dest_tag == .ErrorSet and src_tag == .ErrorSet) { - return try sema.coerceInMemoryAllowedErrorSets(dest_ty, src_ty); + return try sema.coerceInMemoryAllowedErrorSets(block, dest_ty, src_ty, dest_src, src_src); } // Arrays @@ -16646,8 +16646,11 @@ fn coerceInMemoryAllowed( fn coerceInMemoryAllowedErrorSets( sema: *Sema, + block: *Block, dest_ty: Type, src_ty: Type, + dest_src: LazySrcLoc, + src_src: LazySrcLoc, ) !InMemoryCoercionResult { // Coercion to `anyerror`. Note that this check can return false negatives // in case the error sets did not get resolved. @@ -16655,24 +16658,43 @@ fn coerceInMemoryAllowedErrorSets( return .ok; } - // If both are inferred error sets of functions, and - // the dest includes the source function, the coercion is OK. - // This check is important because it works without forcing a full resolution - // of inferred error sets. - if (src_ty.castTag(.error_set_inferred)) |src_payload| { - if (dest_ty.castTag(.error_set_inferred)) |dst_payload| { - const src_func = src_payload.data.func; - const dst_func = dst_payload.data.func; - - if (src_func == dst_func or dst_payload.data.inferred_error_sets.contains(src_payload.data)) { - return .ok; - } - return .no_match; + if (dest_ty.castTag(.error_set_inferred)) |dst_payload| { + const dst_ies = dst_payload.data; + // We will make an effort to return `ok` without resolving either error set, to + // avoid unnecessary "unable to resolve error set" dependency loop errors. + switch (src_ty.tag()) { + .error_set_inferred => { + // If both are inferred error sets of functions, and + // the dest includes the source function, the coercion is OK. + // This check is important because it works without forcing a full resolution + // of inferred error sets. + const src_ies = src_ty.castTag(.error_set_inferred).?.data; + + if (dst_ies.inferred_error_sets.contains(src_ies)) { + return .ok; + } + }, + .error_set_single => { + const name = src_ty.castTag(.error_set_single).?.data; + if (dst_ies.errors.contains(name)) return .ok; + }, + .error_set_merged => { + const names = src_ty.castTag(.error_set_merged).?.data.keys(); + for (names) |name| { + if (!dst_ies.errors.contains(name)) break; + } else return .ok; + }, + .error_set => { + const names = src_ty.castTag(.error_set).?.data.names.keys(); + for (names) |name| { + if (!dst_ies.errors.contains(name)) break; + } else return .ok; + }, + .anyerror => {}, + else => unreachable, } - } - if (dest_ty.castTag(.error_set_inferred)) |payload| { - try sema.resolveInferredErrorSet(payload.data); + try sema.resolveInferredErrorSet(block, dest_src, dst_payload.data); // isAnyError might have changed from a false negative to a true positive after resolution. if (dest_ty.isAnyError()) { return .ok; @@ -16683,7 +16705,7 @@ fn coerceInMemoryAllowedErrorSets( .error_set_inferred => { const src_data = src_ty.castTag(.error_set_inferred).?.data; - try sema.resolveInferredErrorSet(src_data); + try sema.resolveInferredErrorSet(block, src_src, src_data); // src anyerror status might have changed after the resolution. if (src_ty.isAnyError()) { // dest_ty.isAnyError() == true is already checked for at this point. @@ -17969,6 +17991,17 @@ fn ensureDeclAnalyzed(sema: *Sema, decl: *Decl) CompileError!void { }; } +fn ensureFuncBodyAnalyzed(sema: *Sema, func: *Module.Fn) CompileError!void { + sema.mod.ensureFuncBodyAnalyzed(func) catch |err| { + if (sema.owner_func) |owner_func| { + owner_func.state = .dependency_failure; + } else { + sema.owner_decl.analysis = .dependency_failure; + } + return err; + }; +} + fn refValue(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type, val: Value) !Value { var anon_decl = try block.startAnonDecl(src); defer anon_decl.deinit(); @@ -18635,10 +18668,16 @@ fn wrapErrorUnionSet( }, .error_set_inferred => ok: { const expected_name = val.castTag(.@"error").?.data.name; - const data = dest_err_set_ty.castTag(.error_set_inferred).?.data; - try sema.resolveInferredErrorSet(data); - if (data.is_anyerror) break :ok; - if (data.errors.contains(expected_name)) break :ok; + const ies = dest_err_set_ty.castTag(.error_set_inferred).?.data; + + // We carefully do this in an order that avoids unnecessarily + // resolving the destination error set type. + if (ies.is_anyerror) break :ok; + if (ies.errors.contains(expected_name)) break :ok; + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) { + break :ok; + } + return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty); }, .error_set_merged => { @@ -18794,10 +18833,10 @@ fn resolvePeerTypes( // If neither is a superset, merge errors. const chosen_set_ty = err_set_ty orelse chosen_ty; - if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_ty)) { + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_ty, src, src)) { continue; } - if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_ty, chosen_set_ty)) { + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_ty, chosen_set_ty, src, src)) { err_set_ty = null; chosen = candidate; chosen_i = candidate_i + 1; @@ -18810,10 +18849,10 @@ fn resolvePeerTypes( .ErrorUnion => { const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet(); - if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_ty)) { + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_ty, src, src)) { continue; } - if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_ty, chosen_set_ty)) { + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_ty, chosen_set_ty, src, src)) { err_set_ty = candidate_ty; continue; } @@ -18823,10 +18862,10 @@ fn resolvePeerTypes( }, else => { if (err_set_ty) |chosen_set_ty| { - if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_ty)) { + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_ty, src, src)) { continue; } - if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_ty, chosen_set_ty)) { + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_ty, chosen_set_ty, src, src)) { err_set_ty = candidate_ty; continue; } @@ -18844,9 +18883,9 @@ fn resolvePeerTypes( const chosen_set_ty = err_set_ty orelse chosen_ty; const candidate_set_ty = candidate_ty.errorUnionSet(); - if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_set_ty)) { + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) { err_set_ty = chosen_set_ty; - } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_set_ty, chosen_set_ty)) { + } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) { err_set_ty = null; } else { err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty); @@ -18875,9 +18914,9 @@ fn resolvePeerTypes( const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet(); const candidate_set_ty = chosen_ty.errorUnionSet(); - if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_set_ty)) { + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) { err_set_ty = chosen_set_ty; - } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_set_ty, chosen_set_ty)) { + } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) { err_set_ty = candidate_set_ty; } else { err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty); @@ -18889,9 +18928,9 @@ fn resolvePeerTypes( else => { if (err_set_ty) |chosen_set_ty| { const candidate_set_ty = candidate_ty.errorUnionSet(); - if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_set_ty)) { + if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) { err_set_ty = chosen_set_ty; - } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_set_ty, chosen_set_ty)) { + } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) { err_set_ty = null; } else { err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty); @@ -19458,43 +19497,44 @@ fn resolveBuiltinTypeFields( return sema.resolveTypeFields(block, src, resolved_ty); } -fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredErrorSet) CompileError!void { - // Ensuring that a particular decl is analyzed does not neccesarily mean that - // it's error set is inferred, so traverse all of them to get the complete - // picture. - // Note: We want to skip re-resolving the current function, as recursion - // doesn't change the error set. We can just check for state == .in_progress for this. - // TODO: Is that correct? +fn resolveInferredErrorSet( + sema: *Sema, + block: *Block, + src: LazySrcLoc, + ies: *Module.Fn.InferredErrorSet, +) CompileError!void { + if (ies.is_resolved) return; - if (inferred_error_set.is_resolved) { - return; + if (ies.func.state == .in_progress) { + return sema.fail(block, src, "unable to resolve inferred error set", .{}); } - inferred_error_set.is_resolved = true; - var it = inferred_error_set.inferred_error_sets.keyIterator(); - while (it.next()) |other_error_set_ptr| { - const func = other_error_set_ptr.*.func; - const decl = func.*.owner_decl; + // To ensure that all dependencies are properly added to the set. + try sema.ensureFuncBodyAnalyzed(ies.func); - if (func.*.state == .in_progress) { - // Recursion, doesn't alter current error set, keep going. - continue; - } + ies.is_resolved = true; - try sema.ensureDeclAnalyzed(decl); // To ensure that all dependencies are properly added to the set. - try sema.resolveInferredErrorSet(other_error_set_ptr.*); + var it = ies.inferred_error_sets.keyIterator(); + while (it.next()) |other_error_set_ptr| { + const other_ies: *Module.Fn.InferredErrorSet = other_error_set_ptr.*; + try sema.resolveInferredErrorSet(block, src, other_ies); - for (other_error_set_ptr.*.errors.keys()) |key| { - try inferred_error_set.errors.put(sema.gpa, key, {}); + for (other_ies.errors.keys()) |key| { + try ies.errors.put(sema.gpa, key, {}); } - if (other_error_set_ptr.*.is_anyerror) - inferred_error_set.is_anyerror = true; + if (other_ies.is_anyerror) + ies.is_anyerror = true; } } -fn resolveInferredErrorSetTy(sema: *Sema, ty: Type) CompileError!void { +fn resolveInferredErrorSetTy( + sema: *Sema, + block: *Block, + src: LazySrcLoc, + ty: Type, +) CompileError!void { if (ty.castTag(.error_set_inferred)) |inferred| { - try sema.resolveInferredErrorSet(inferred.data); + try sema.resolveInferredErrorSet(block, src, inferred.data); } } diff --git a/src/type.zig b/src/type.zig index ae9ca31e9f..04bd015bcc 100644 --- a/src/type.zig +++ b/src/type.zig @@ -559,9 +559,9 @@ pub const Type = extern union { .error_set_inferred => { // Inferred error sets are only equal if both are inferred // and they originate from the exact same function. - const a_set = a.castTag(.error_set_inferred).?.data; - const b_set = (b.castTag(.error_set_inferred) orelse return false).data; - return a_set.func == b_set.func; + const a_ies = a.castTag(.error_set_inferred).?.data; + const b_ies = (b.castTag(.error_set_inferred) orelse return false).data; + return a_ies == b_ies; }, .anyerror => { @@ -983,10 +983,10 @@ pub const Type = extern union { .error_set_inferred => { // inferred error sets are compared using their data pointer - const set = ty.castTag(.error_set_inferred).?.data; + const ies: *Module.Fn.InferredErrorSet = ty.castTag(.error_set_inferred).?.data; std.hash.autoHash(hasher, std.builtin.TypeId.ErrorSet); std.hash.autoHash(hasher, Tag.error_set_inferred); - std.hash.autoHash(hasher, set.func); + std.hash.autoHash(hasher, ies); }, .@"opaque" => { diff --git a/test/behavior.zig b/test/behavior.zig index 0b008409fd..7efe687c75 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -61,6 +61,7 @@ test { _ = @import("behavior/bugs/7250.zig"); _ = @import("behavior/bugs/11100.zig"); _ = @import("behavior/bugs/10970.zig"); + _ = @import("behavior/bugs/11046.zig"); _ = @import("behavior/call.zig"); _ = @import("behavior/cast.zig"); _ = @import("behavior/comptime_memory.zig"); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index eb8ae8972d..3d39942e3d 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -538,9 +538,6 @@ test "type coercion of anon struct literal to array" { try expect(arr1[1] == 56); try expect(arr1[2] == 54); - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - var x2: U = .{ .a = 42 }; const t2 = .{ x2, .{ .b = true }, .{ .c = "hello" } }; var arr2: [3]U = t2; diff --git a/test/behavior/bugs/11046.zig b/test/behavior/bugs/11046.zig new file mode 100644 index 0000000000..4fcd33deb4 --- /dev/null +++ b/test/behavior/bugs/11046.zig @@ -0,0 +1,21 @@ +const builtin = @import("builtin"); + +fn foo() !void { + var a = true; + if (a) return error.Foo; + return error.Bar; +} +fn bar() !void { + try foo(); +} + +test "fixed" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + bar() catch |err| switch (err) { + error.Foo => {}, // error: expected (inferred error set of bar), found error{Foo} + error.Bar => {}, + }; +} diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 0a55b34121..b3503051fb 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -476,7 +476,11 @@ test "function pointer with return type that is error union with payload which i } test "return result loc as peer result loc in inferred error set function" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { -- cgit v1.2.3 From b74cd902c6abf46644329409dae493335a1708bc Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Sat, 12 Mar 2022 21:02:53 +0100 Subject: stage2 AArch64: enable mul for ints with <= 64 bits --- src/arch/aarch64/CodeGen.zig | 12 ++++-------- test/behavior/align.zig | 1 - test/behavior/array.zig | 1 - test/behavior/bitcast.zig | 1 - test/behavior/bugs/5474.zig | 2 -- test/behavior/math.zig | 1 - test/behavior/sizeof_and_typeof.zig | 2 -- test/behavior/slice.zig | 1 - test/behavior/struct.zig | 3 --- test/behavior/var_args.zig | 4 ---- 10 files changed, 4 insertions(+), 24 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 5e9f1ecd81..9534e31a01 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -538,7 +538,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .sub, .ptr_sub => try self.airBinOp(inst), .subwrap => try self.airSubWrap(inst), .sub_sat => try self.airSubSat(inst), - .mul => try self.airMul(inst), + .mul => try self.airBinOp(inst), .mulwrap => try self.airMulWrap(inst), .mul_sat => try self.airMulSat(inst), .rem => try self.airRem(inst), @@ -820,7 +820,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { const elem_ty = self.air.typeOfIndex(inst).elemType(); if (!elem_ty.hasRuntimeBits()) { - return self.allocMem(inst, @sizeOf(usize), @alignOf(usize)); + // As this stack item will never be dereferenced at runtime, + // return the current stack offset + return self.next_stack_offset; } const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch { @@ -1540,12 +1542,6 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } -fn airMul(self: *Self, inst: Air.Inst.Index) !void { - const bin_op = self.air.instructions.items(.data)[inst].bin_op; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul for {}", .{self.target.cpu.arch}); - return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); -} - fn airMulWrap(self: *Self, inst: Air.Inst.Index) !void { const bin_op = self.air.instructions.items(.data)[inst].bin_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mulwrap for {}", .{self.target.cpu.arch}); diff --git a/test/behavior/align.zig b/test/behavior/align.zig index fa74138d01..5cc601e9e2 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -351,7 +351,6 @@ test "read 128-bit field from default aligned struct in global memory" { } test "struct field explicit alignment" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 3d39942e3d..098d3d343c 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -7,7 +7,6 @@ const expectEqual = testing.expectEqual; test "array to slice" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const a: u32 align(4) = 3; const b: u32 align(8) = 4; diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index 6f647cbc79..a881f98e3d 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -269,7 +269,6 @@ test "bitcast passed as tuple element" { test "triple level result location with bitcast sandwich passed as tuple element" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { diff --git a/test/behavior/bugs/5474.zig b/test/behavior/bugs/5474.zig index e0384b244c..1ee5b99d79 100644 --- a/test/behavior/bugs/5474.zig +++ b/test/behavior/bugs/5474.zig @@ -50,7 +50,6 @@ fn constant() !void { test "pointer-to-array constness for zero-size elements, var" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try mutable(); comptime try mutable(); @@ -58,7 +57,6 @@ test "pointer-to-array constness for zero-size elements, var" { test "pointer-to-array constness for zero-size elements, const" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try constant(); comptime try constant(); diff --git a/test/behavior/math.zig b/test/behavior/math.zig index 413cf53044..c6fc43e38c 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -573,7 +573,6 @@ test "bit shift a u1" { test "truncating shift right" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO -// if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try testShrTrunc(maxInt(u16)); comptime try testShrTrunc(maxInt(u16)); diff --git a/test/behavior/sizeof_and_typeof.zig b/test/behavior/sizeof_and_typeof.zig index 75db442fc7..5b532761f3 100644 --- a/test/behavior/sizeof_and_typeof.zig +++ b/test/behavior/sizeof_and_typeof.zig @@ -187,7 +187,6 @@ test "@sizeOf(T) == 0 doesn't force resolving struct size" { test "@TypeOf() has no runtime side effects" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; const S = struct { @@ -204,7 +203,6 @@ test "@TypeOf() has no runtime side effects" { test "branching logic inside @TypeOf" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; const S = struct { diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index d7d6233c90..d36e9815eb 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -204,7 +204,6 @@ test "slicing zero length array" { const x = @intToPtr([*]i32, 0x1000)[0..0x500]; const y = x[0x100..]; test "compile time slice of pointer to hard coded address" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 6e48f7ca21..abd24967bb 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -927,7 +927,6 @@ test "anonymous struct literal syntax" { test "fully anonymous struct" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -953,7 +952,6 @@ test "fully anonymous struct" { test "fully anonymous list literal" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -983,7 +981,6 @@ test "tuple assigned to variable" { test "comptime struct field" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const T = struct { a: i32, diff --git a/test/behavior/var_args.zig b/test/behavior/var_args.zig index d73f864675..5cb498d169 100644 --- a/test/behavior/var_args.zig +++ b/test/behavior/var_args.zig @@ -15,7 +15,6 @@ fn add(args: anytype) i32 { test "add arbitrary args" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10); try expect(add(.{@as(i32, 1234)}) == 1234); @@ -27,7 +26,6 @@ fn readFirstVarArg(args: anytype) void { } test "send void arg to var args" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -90,7 +88,6 @@ fn foo2(args: anytype) bool { } test "array of var args functions" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -99,7 +96,6 @@ test "array of var args functions" { } test "pass zero length array to var args param" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO -- cgit v1.2.3 From ca1ffb0951a0bd039ac435435a5c396f26c6d141 Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Sat, 12 Mar 2022 22:30:28 +0100 Subject: stage2 ARM: genSetStack for stack_argument_offset --- src/arch/arm/CodeGen.zig | 44 ++++++++++------------- src/arch/arm/Emit.zig | 7 ++++ src/arch/arm/Mir.zig | 2 ++ test/behavior/array.zig | 1 - test/behavior/bitcast.zig | 1 - test/behavior/bugs/1421.zig | 1 - test/behavior/bugs/2692.zig | 1 - test/behavior/bugs/5474.zig | 4 --- test/behavior/bugs/828.zig | 1 - test/behavior/cast.zig | 3 -- test/behavior/optional.zig | 1 - test/behavior/sizeof_and_typeof.zig | 1 - test/behavior/slice.zig | 2 -- test/behavior/struct.zig | 2 -- test/behavior/struct_contains_null_ptr_itself.zig | 1 - test/behavior/var_args.zig | 5 --- 16 files changed, 27 insertions(+), 50 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 0ccec1be88..28899383e1 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -2876,35 +2876,19 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { const condition = Condition.fromCompareOperatorUnsigned(cmp_op); break :blk condition.negate(); }, - .register => |reg| blk: { - try self.spillCompareFlagsIfOccupied(); - - // cmp reg, 1 - // bne ... - _ = try self.addInst(.{ - .tag = .cmp, - .cond = .al, - .data = .{ .rr_op = .{ - .rd = .r0, - .rn = reg, - .op = Instruction.Operand.imm(1, 0), - } }, - }); + else => blk: { + const reg = switch (cond) { + .register => |r| r, + else => try self.copyToTmpRegister(Type.bool, cond), + }; - break :blk .ne; - }, - .stack_offset, - .memory, - .stack_argument_offset, - => blk: { try self.spillCompareFlagsIfOccupied(); - const reg = try self.copyToTmpRegister(Type.initTag(.bool), cond); - // cmp reg, 1 // bne ... _ = try self.addInst(.{ .tag = .cmp, + .cond = .al, .data = .{ .rr_op = .{ .rd = .r0, .rn = reg, @@ -2914,7 +2898,6 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { break :blk .ne; }, - else => return self.fail("TODO implement condbr {} when condition is {s}", .{ self.target.cpu.arch, @tagName(cond) }), }; break :reloc try self.addInst(.{ @@ -3603,9 +3586,18 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off }); }, .memory => |addr| try self.genSetReg(ptr_ty, src_reg, .{ .immediate = @intCast(u32, addr) }), - .embedded_in_code, - .stack_argument_offset, - => return self.fail("TODO genSetStack with src={}", .{mcv}), + .stack_argument_offset => |unadjusted_off| { + const adj_off = unadjusted_off + abi_size; + + _ = try self.addInst(.{ + .tag = .ldr_ptr_stack_argument, + .data = .{ .r_stack_offset = .{ + .rt = src_reg, + .stack_offset = adj_off, + } }, + }); + }, + .embedded_in_code => return self.fail("TODO genSetStack with src={}", .{mcv}), else => unreachable, } diff --git a/src/arch/arm/Emit.zig b/src/arch/arm/Emit.zig index 963879519f..c5aaeb4612 100644 --- a/src/arch/arm/Emit.zig +++ b/src/arch/arm/Emit.zig @@ -112,6 +112,7 @@ pub fn emitMir( .str => try emit.mirLoadStore(inst), .strb => try emit.mirLoadStore(inst), + .ldr_ptr_stack_argument => try emit.mirLoadStackArgument(inst), .ldr_stack_argument => try emit.mirLoadStackArgument(inst), .ldrb_stack_argument => try emit.mirLoadStackArgument(inst), .ldrh_stack_argument => try emit.mirLoadStackArgument(inst), @@ -597,6 +598,12 @@ fn mirLoadStackArgument(emit: *Emit, inst: Mir.Inst.Index) !void { const raw_offset = emit.prologue_stack_space - r_stack_offset.stack_offset; switch (tag) { + .ldr_ptr_stack_argument => { + const operand = Instruction.Operand.fromU32(raw_offset) orelse + return emit.fail("TODO mirLoadStack larger offsets", .{}); + + try emit.writeInstruction(Instruction.add(cond, r_stack_offset.rt, .fp, operand)); + }, .ldr_stack_argument, .ldrb_stack_argument, => { diff --git a/src/arch/arm/Mir.zig b/src/arch/arm/Mir.zig index 5dcc3f7095..c6fdfd3051 100644 --- a/src/arch/arm/Mir.zig +++ b/src/arch/arm/Mir.zig @@ -54,6 +54,8 @@ pub const Inst = struct { eor, /// Load Register ldr, + /// Pseudo-instruction: Load pointer to stack argument offset + ldr_ptr_stack_argument, /// Load Register ldr_stack_argument, /// Load Register Byte diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 098d3d343c..89c7412e66 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -202,7 +202,6 @@ fn doSomeMangling(array: *[4]u8) void { test "implicit cast zero sized array ptr to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; { var b = "".*; diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index a881f98e3d..99451e8442 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -269,7 +269,6 @@ test "bitcast passed as tuple element" { test "triple level result location with bitcast sandwich passed as tuple element" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn foo(args: anytype) !void { diff --git a/test/behavior/bugs/1421.zig b/test/behavior/bugs/1421.zig index e8aceeecaf..e4e42bd21b 100644 --- a/test/behavior/bugs/1421.zig +++ b/test/behavior/bugs/1421.zig @@ -9,7 +9,6 @@ const S = struct { }; test "functions with return type required to be comptime are generic" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; diff --git a/test/behavior/bugs/2692.zig b/test/behavior/bugs/2692.zig index af53888a17..36fd763ebd 100644 --- a/test/behavior/bugs/2692.zig +++ b/test/behavior/bugs/2692.zig @@ -6,7 +6,6 @@ fn foo(a: []u8) void { test "address of 0 length array" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var pt: [0]u8 = undefined; diff --git a/test/behavior/bugs/5474.zig b/test/behavior/bugs/5474.zig index 1ee5b99d79..62d7a52a3f 100644 --- a/test/behavior/bugs/5474.zig +++ b/test/behavior/bugs/5474.zig @@ -49,15 +49,11 @@ fn constant() !void { } test "pointer-to-array constness for zero-size elements, var" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - try mutable(); comptime try mutable(); } test "pointer-to-array constness for zero-size elements, const" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - try constant(); comptime try constant(); } diff --git a/test/behavior/bugs/828.zig b/test/behavior/bugs/828.zig index a8253e0c4c..220d98ce09 100644 --- a/test/behavior/bugs/828.zig +++ b/test/behavior/bugs/828.zig @@ -30,7 +30,6 @@ fn constCount(comptime cb: *const CountBy, comptime unused: u32) void { } test "comptime struct return should not return the same instance" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; //the first parameter must be passed by reference to trigger the bug diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 764e3b77b4..be8859c0bc 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1129,7 +1129,6 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A { test "peer type resolution: [0]u8 and []const u8" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); @@ -1278,8 +1277,6 @@ test "assignment to optional pointer result loc" { } test "cast between *[N]void and []void" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - var a: [4]void = undefined; var b: []void = &a; try expect(b.len == 4); diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index 6cc174dbba..08adda259d 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -26,7 +26,6 @@ pub const EmptyStruct = struct {}; test "optional pointer to size zero struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var e = EmptyStruct{}; var o: ?*EmptyStruct = &e; diff --git a/test/behavior/sizeof_and_typeof.zig b/test/behavior/sizeof_and_typeof.zig index 5b532761f3..5db56243af 100644 --- a/test/behavior/sizeof_and_typeof.zig +++ b/test/behavior/sizeof_and_typeof.zig @@ -186,7 +186,6 @@ test "@sizeOf(T) == 0 doesn't force resolving struct size" { } test "@TypeOf() has no runtime side effects" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; const S = struct { diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index d36e9815eb..613493e690 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -70,7 +70,6 @@ test "comptime slice of undefined pointer of length 0" { test "implicitly cast array of size 0 to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var msg = [_]u8{}; try assertLenIsZero(&msg); @@ -206,7 +205,6 @@ const y = x[0x100..]; test "compile time slice of pointer to hard coded address" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 1d52900796..2cda0ca3bd 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -926,7 +926,6 @@ test "anonymous struct literal syntax" { test "fully anonymous struct" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -951,7 +950,6 @@ test "fully anonymous struct" { test "fully anonymous list literal" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { diff --git a/test/behavior/struct_contains_null_ptr_itself.zig b/test/behavior/struct_contains_null_ptr_itself.zig index ce4f63f976..7a2e32b2c2 100644 --- a/test/behavior/struct_contains_null_ptr_itself.zig +++ b/test/behavior/struct_contains_null_ptr_itself.zig @@ -3,7 +3,6 @@ const expect = std.testing.expect; const builtin = @import("builtin"); test "struct contains null pointer which contains original struct" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; diff --git a/test/behavior/var_args.zig b/test/behavior/var_args.zig index 5cb498d169..21085dd92e 100644 --- a/test/behavior/var_args.zig +++ b/test/behavior/var_args.zig @@ -14,7 +14,6 @@ fn add(args: anytype) i32 { test "add arbitrary args" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10); try expect(add(.{@as(i32, 1234)}) == 1234); @@ -27,14 +26,12 @@ fn readFirstVarArg(args: anytype) void { test "send void arg to var args" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO readFirstVarArg(.{{}}); } test "pass args directly" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10); @@ -89,7 +86,6 @@ fn foo2(args: anytype) bool { test "array of var args functions" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try expect(foos[0](.{})); try expect(!foos[1](.{})); @@ -97,7 +93,6 @@ test "array of var args functions" { test "pass zero length array to var args param" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO doNothingWithFirstArg(.{""}); } -- cgit v1.2.3 From 312536540baf26728a56304811f63f01a7414b7a Mon Sep 17 00:00:00 2001 From: Daniele Cocca Date: Tue, 15 Mar 2022 21:53:48 +0000 Subject: CBE: better handling of sentineled slices/arrays Adds the sentinel element to the type name to avoid ambiguous declarations, and outputs the sentinel element (if needed) even in what would otherwise be empty arrays. --- src/codegen/c.zig | 37 +++++++++++++++++++++++++------------ test/behavior/array.zig | 11 ----------- 2 files changed, 25 insertions(+), 23 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 358e7354dd..c0c2031116 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -616,27 +616,33 @@ pub const DeclGen = struct { .Array => { // First try specific tag representations for more efficiency. switch (val.tag()) { - .undef, .empty_struct_value, .empty_array => try writer.writeAll("{}"), + .undef, .empty_struct_value, .empty_array => { + try writer.writeByte('{'); + const ai = ty.arrayInfo(); + if (ai.sentinel) |s| { + try dg.renderValue(writer, ai.elem_type, s); + } + try writer.writeByte('}'); + }, else => { // Fall back to generic implementation. var arena = std.heap.ArenaAllocator.init(dg.module.gpa); defer arena.deinit(); const arena_allocator = arena.allocator(); - try writer.writeAll("{"); + try writer.writeByte('{'); + const ai = ty.arrayInfo(); var index: usize = 0; - const len = ty.arrayLen(); - const elem_ty = ty.elemType(); - while (index < len) : (index += 1) { + while (index < ai.len) : (index += 1) { if (index != 0) try writer.writeAll(","); const elem_val = try val.elemValue(arena_allocator, index); - try dg.renderValue(writer, elem_ty, elem_val); + try dg.renderValue(writer, ai.elem_type, elem_val); } - if (ty.sentinel()) |sentinel_val| { + if (ai.sentinel) |s| { if (index != 0) try writer.writeAll(","); - try dg.renderValue(writer, elem_ty, sentinel_val); + try dg.renderValue(writer, ai.elem_type, s); } - try writer.writeAll("}"); + try writer.writeByte('}'); }, } }, @@ -925,14 +931,21 @@ pub const DeclGen = struct { const ptr_alignment = Value.initTag(.abi_align_default); try dg.renderTypeAndName(bw, ptr_type, ptr_name, .Mut, ptr_alignment); + const ptr_sentinel = ptr_type.ptrInfo().data.sentinel; + const child_type = t.childType(); + try bw.writeAll("; size_t len; } "); const name_index = buffer.items.len; - const elem_type = t.elemType(); if (t.isConstPtr()) { - try bw.print("zig_L_{s};\n", .{typeToCIdentifier(elem_type)}); + try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type)}); } else { - try bw.print("zig_M_{s};\n", .{typeToCIdentifier(elem_type)}); + try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type)}); + } + if (ptr_sentinel) |s| { + try bw.writeAll("_s_"); + try dg.renderValue(bw, child_type, s); } + try bw.writeAll(";\n"); const rendered = buffer.toOwnedSlice(); errdefer dg.typedefs.allocator.free(rendered); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 098d3d343c..4561db792f 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -238,7 +238,6 @@ const Sub = struct { b: u8 }; const Str = struct { a: []Sub }; test "set global var array via slice embedded in struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var s = Str{ .a = s_array[0..] }; @@ -254,7 +253,6 @@ test "set global var array via slice embedded in struct" { test "read/write through global variable array of struct fields initialized via array mult" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -275,7 +273,6 @@ test "read/write through global variable array of struct fields initialized via test "implicit cast single-item pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testImplicitCastSingleItemPtr(); @@ -295,7 +292,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 { test "comptime evaluating function that takes array by value" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const arr = [_]u8{ 1, 2 }; @@ -307,7 +303,6 @@ test "comptime evaluating function that takes array by value" { test "runtime initialize array elem and then implicit cast to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var two: i32 = 2; @@ -317,7 +312,6 @@ test "runtime initialize array elem and then implicit cast to slice" { test "array literal as argument to function" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -345,7 +339,6 @@ test "array literal as argument to function" { test "double nested array to const slice cast in array literal" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -406,7 +399,6 @@ test "double nested array to const slice cast in array literal" { test "anonymous literal in array" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -431,7 +423,6 @@ test "anonymous literal in array" { test "access the null element of a null terminated array" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -448,7 +439,6 @@ test "access the null element of a null terminated array" { test "type deduction for array subscript expression" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -468,7 +458,6 @@ test "sentinel element count towards the ABI size calculation" { if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO -- cgit v1.2.3 From 3ecba7d7a2f527d4f579a1156e26cd2f0c14c2a0 Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Thu, 17 Mar 2022 09:57:10 +0100 Subject: stage2 ARM: implement slice_elem_ptr, ptr_elem_ptr --- src/arch/arm/CodeGen.zig | 88 +++++++++++++++++++++++++++++++--------------- test/behavior/align.zig | 1 - test/behavior/array.zig | 1 - test/behavior/basic.zig | 1 - test/behavior/optional.zig | 1 - test/behavior/struct.zig | 1 - 6 files changed, 60 insertions(+), 33 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index f2283bd3df..25f34db921 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -1358,24 +1358,28 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } +fn slicePtr(self: *Self, mcv: MCValue) !MCValue { + switch (mcv) { + .dead, .unreach => unreachable, + .register => unreachable, // a slice doesn't fit in one register + .stack_argument_offset => |off| { + return MCValue{ .stack_argument_offset = off + 4 }; + }, + .stack_offset => |off| { + return MCValue{ .stack_offset = off + 4 }; + }, + .memory => |addr| { + return MCValue{ .memory = addr }; + }, + else => return self.fail("TODO implement slice_ptr for {}", .{mcv}), + } +} + fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const mcv = try self.resolveInst(ty_op.operand); - switch (mcv) { - .dead, .unreach => unreachable, - .register => unreachable, // a slice doesn't fit in one register - .stack_argument_offset => |off| { - break :result MCValue{ .stack_argument_offset = off + 4 }; - }, - .stack_offset => |off| { - break :result MCValue{ .stack_offset = off + 4 }; - }, - .memory => |addr| { - break :result MCValue{ .memory = addr }; - }, - else => return self.fail("TODO implement slice_ptr for {}", .{mcv}), - } + break :result try self.slicePtr(mcv); }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -1409,7 +1413,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { switch (mcv) { .dead, .unreach => unreachable, .ptr_stack_offset => |off| { - break :result MCValue{ .ptr_stack_offset = off + 4 }; + break :result MCValue{ .ptr_stack_offset = off }; }, else => return self.fail("TODO implement ptr_slice_len_ptr for {}", .{mcv}), } @@ -1424,7 +1428,7 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { switch (mcv) { .dead, .unreach => unreachable, .ptr_stack_offset => |off| { - break :result MCValue{ .ptr_stack_offset = off }; + break :result MCValue{ .ptr_stack_offset = off + 4 }; }, else => return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{mcv}), } @@ -1455,15 +1459,17 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { if (index_is_register) self.register_manager.freezeRegs(&.{index_mcv.register}); defer if (index_is_register) self.register_manager.unfreezeRegs(&.{index_mcv.register}); - const base_mcv: MCValue = switch (slice_mcv) { - .stack_offset => |off| .{ .register = try self.copyToTmpRegister(slice_ptr_field_type, .{ .stack_offset = off + 4 }) }, - .stack_argument_offset => |off| .{ .register = try self.copyToTmpRegister(slice_ptr_field_type, .{ .stack_argument_offset = off + 4 }) }, - else => return self.fail("TODO slice_elem_val when slice is {}", .{slice_mcv}), - }; - self.register_manager.freezeRegs(&.{base_mcv.register}); + const base_mcv = try self.slicePtr(slice_mcv); switch (elem_size) { 1, 4 => { + const base_reg = switch (base_mcv) { + .register => |r| r, + else => try self.copyToTmpRegister(slice_ptr_field_type, base_mcv), + }; + self.register_manager.freezeRegs(&.{base_reg}); + defer self.register_manager.unfreezeRegs(&.{base_reg}); + const dst_reg = try self.register_manager.allocReg(inst); const dst_mcv = MCValue{ .register = dst_reg }; self.register_manager.freezeRegs(&.{dst_reg}); @@ -1491,13 +1497,11 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { .tag = tag, .data = .{ .rr_offset = .{ .rt = dst_reg, - .rn = base_mcv.register, + .rn = base_reg, .offset = .{ .offset = Instruction.Offset.reg(index_reg, .{ .lsl = shift }) }, } }, }); - self.register_manager.unfreezeRegs(&.{base_mcv.register}); - break :result dst_mcv; }, else => { @@ -1515,7 +1519,16 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_elem_ptr for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const slice_mcv = try self.resolveInst(extra.lhs); + const index_mcv = try self.resolveInst(extra.rhs); + const base_mcv = try self.slicePtr(slice_mcv); + + const slice_ty = self.air.typeOf(extra.lhs); + + const addr = try self.binOp(.ptr_add, null, base_mcv, index_mcv, slice_ty, Type.usize); + break :result addr; + }; return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); } @@ -1535,7 +1548,15 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_elem_ptr for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const ptr_mcv = try self.resolveInst(extra.lhs); + const index_mcv = try self.resolveInst(extra.rhs); + + const ptr_ty = self.air.typeOf(extra.lhs); + + const addr = try self.binOp(.ptr_add, null, ptr_mcv, index_mcv, ptr_ty, Type.usize); + break :result addr; + }; return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); } @@ -1760,7 +1781,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type try self.genStrRegister(value_reg, addr_reg, value_ty); }, else => { - if (value_ty.abiSize(self.target.*) <= 4) { + if (elem_size <= 4) { const tmp_reg = try self.register_manager.allocReg(null); self.register_manager.freezeRegs(&.{tmp_reg}); defer self.register_manager.unfreezeRegs(&.{tmp_reg}); @@ -1784,6 +1805,17 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off }); }, .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = @intCast(u32, addr) }), + .stack_argument_offset => |unadjusted_off| { + const adj_off = unadjusted_off + elem_size; + + _ = try self.addInst(.{ + .tag = .ldr_ptr_stack_argument, + .data = .{ .r_stack_offset = .{ + .rt = src_reg, + .stack_offset = adj_off, + } }, + }); + }, else => return self.fail("TODO store {} to register", .{value}), } diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 5cc601e9e2..ef5a790ead 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -115,7 +115,6 @@ fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { test "specifying alignment allows pointer cast" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try testBytesAlign(0x33); } diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 67776f2db4..992ed14526 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -272,7 +272,6 @@ test "read/write through global variable array of struct fields initialized via test "implicit cast single-item pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testImplicitCastSingleItemPtr(); comptime try testImplicitCastSingleItemPtr(); diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index 889519b056..43967ee0e5 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -636,7 +636,6 @@ var global_ptr = &gdt[0]; test "global constant is loaded with a runtime-known index" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest() !void { diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index 08adda259d..d9c16da066 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -275,7 +275,6 @@ test "0-bit child type coerced to optional" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index da7d1d7420..53ebe423cf 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -1289,7 +1289,6 @@ test "initialize struct with empty literal" { test "loading a struct pointer perfoms a copy" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { a: i32, -- cgit v1.2.3 From 2fc91a09a2bcefdd2af2370cf6d24bc23e186425 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Sat, 19 Mar 2022 20:53:39 +0100 Subject: wasm: Enable passing tests This enables the tests that now pass due to the changes to lower parent pointers are lowered, as well as the additional features to unions. --- test/behavior/array.zig | 2 -- test/behavior/slice.zig | 2 -- test/behavior/tuple.zig | 3 --- test/behavior/union.zig | 7 ------- 4 files changed, 14 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 992ed14526..bbaf3b3c34 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -455,7 +455,6 @@ test "type deduction for array subscript expression" { test "sentinel element count towards the ABI size calculation" { if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -537,7 +536,6 @@ test "type coercion of anon struct literal to array" { } test "type coercion of pointer to anon struct literal to pointer to array" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index f598bccee1..9177ba96ad 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -188,7 +188,6 @@ const y = x[0x100..]; test "compile time slice of pointer to hard coded address" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; try expect(@ptrToInt(x) == 0x1000); try expect(x.len == 0x500); @@ -496,7 +495,6 @@ test "slice syntax resulting in pointer-to-array" { } test "type coercion of pointer to anon struct literal to pointer to slice" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO diff --git a/test/behavior/tuple.zig b/test/behavior/tuple.zig index 71bf52d71e..a51aa466d9 100644 --- a/test/behavior/tuple.zig +++ b/test/behavior/tuple.zig @@ -4,7 +4,6 @@ const testing = std.testing; const expect = testing.expect; test "tuple concatenation" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO @@ -48,7 +47,6 @@ test "tuple multiplication" { } test "more tuple concatenation" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO @@ -126,7 +124,6 @@ test "tuple initializer for var" { } test "array-like initializer for tuple types" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 74df2bf4e4..642a1f6279 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -436,7 +436,6 @@ test "global union with single field is correctly initialized" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO glbl = Foo1{ @@ -453,7 +452,6 @@ pub const FooUnion = union(enum) { var glbl_array: [2]FooUnion = undefined; test "initialize global array of union" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; @@ -610,7 +608,6 @@ test "tagged union with all void fields but a meaningful tag" { } test "union(enum(u32)) with specified and unspecified tag values" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; @@ -783,7 +780,6 @@ test "return union init with void payload" { } test "@unionInit stored to a const" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO @@ -945,7 +941,6 @@ test "function call result coerces from tagged union to the tag" { } test "cast from anonymous struct to union" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO @@ -978,7 +973,6 @@ test "cast from anonymous struct to union" { } test "cast from pointer to anonymous struct to pointer to union" { - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO @@ -1120,7 +1114,6 @@ test "union enum type gets a separate scope" { test "global variable struct contains union initialized to non-most-aligned field" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO -- cgit v1.2.3 From d7530c8f7bb14e860898c74aa6a20d86379c8822 Mon Sep 17 00:00:00 2001 From: William Sengir Date: Wed, 23 Mar 2022 08:44:11 -0700 Subject: stage2: make zero-sized array not cause recursive type definition --- src/Sema.zig | 1 + test/behavior/array.zig | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/Sema.zig b/src/Sema.zig index 1734185073..03a8a89054 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -20816,6 +20816,7 @@ pub fn resolveTypeLayout( .Struct => return sema.resolveStructLayout(block, src, ty), .Union => return sema.resolveUnionLayout(block, src, ty), .Array => { + if (ty.arrayLenIncludingSentinel() == 0) return; const elem_ty = ty.childType(); return sema.resolveTypeLayout(block, src, elem_ty); }, diff --git a/test/behavior/array.zig b/test/behavior/array.zig index bbaf3b3c34..7e55bb13c3 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -479,10 +479,7 @@ test "sentinel element count towards the ABI size calculation" { test "zero-sized array with recursive type definition" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const U = struct { -- cgit v1.2.3 From b872539a13ac46abe57a59bafdf5392812468482 Mon Sep 17 00:00:00 2001 From: William Sengir Date: Wed, 23 Mar 2022 08:49:16 -0700 Subject: stage2: enable some passing array & vector tests --- test/behavior/array.zig | 2 -- test/behavior/math.zig | 12 ++++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 7e55bb13c3..d7a87bed9c 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -453,9 +453,7 @@ test "type deduction for array subscript expression" { } test "sentinel element count towards the ABI size calculation" { - if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { diff --git a/test/behavior/math.zig b/test/behavior/math.zig index 67f7fd101d..6690fbd193 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -1282,7 +1282,11 @@ fn testRound(comptime T: type, x: T) !void { } test "vector integer addition" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -1336,7 +1340,11 @@ fn testNanEqNan(comptime F: type) !void { } test "vector comparison" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { -- cgit v1.2.3 From 4ef26fc35562222263f564ca8d382ecd4b44c0a3 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 24 Mar 2022 17:01:17 +0100 Subject: pass more behaviour tests --- test/behavior/array.zig | 1 - test/behavior/struct.zig | 2 -- test/behavior/tuple.zig | 2 -- 3 files changed, 5 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/test/behavior/array.zig b/test/behavior/array.zig index d7a87bed9c..13a4763a91 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -501,7 +501,6 @@ test "type coercion of anon struct literal to array" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const S = struct { const U = union { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index f9a039208f..4bed1f56cc 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -301,7 +301,6 @@ test "void struct fields" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO const foo = VoidStructFieldsFoo{ .a = void{}, @@ -1019,7 +1018,6 @@ test "struct with union field" { } test "type coercion of anon struct literal to struct" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO diff --git a/test/behavior/tuple.zig b/test/behavior/tuple.zig index a51aa466d9..80eaea5072 100644 --- a/test/behavior/tuple.zig +++ b/test/behavior/tuple.zig @@ -4,7 +4,6 @@ const testing = std.testing; const expect = testing.expect; test "tuple concatenation" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO @@ -47,7 +46,6 @@ test "tuple multiplication" { } test "more tuple concatenation" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO -- cgit v1.2.3 From c992b259085070b4faef10f498840d2d3ce394fa Mon Sep 17 00:00:00 2001 From: Annika L Date: Fri, 1 Apr 2022 00:28:46 -0700 Subject: C backend: Fix array declarations --- src/codegen/c.zig | 66 +++++++++++++++++++++++++++++-------------------- test/behavior/array.zig | 18 +++++++++++++- test/behavior/fn.zig | 11 ++++++++- 3 files changed, 66 insertions(+), 29 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/codegen/c.zig b/src/codegen/c.zig index a0b1bc30b9..464f144f5a 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -61,6 +61,11 @@ const FormatTypeAsCIdentContext = struct { mod: *Module, }; +const ValueRenderLocation = enum { + FunctionArgument, + Other, +}; + /// TODO make this not cut off at 128 bytes fn formatTypeAsCIdentifier( data: FormatTypeAsCIdentContext, @@ -259,7 +264,7 @@ pub const Function = struct { 0, ); try writer.writeAll(" = "); - try f.object.dg.renderValue(writer, ty, val); + try f.object.dg.renderValue(writer, ty, val, .Other); try writer.writeAll(";\n "); return decl_c_value; }, @@ -298,7 +303,7 @@ pub const Function = struct { .constant => |inst| { const ty = f.air.typeOf(inst); const val = f.air.value(inst).?; - return f.object.dg.renderValue(w, ty, val); + return f.object.dg.renderValue(w, ty, val, .Other); }, else => return f.object.dg.writeCValue(w, c_value), } @@ -310,7 +315,7 @@ pub const Function = struct { const ty = f.air.typeOf(inst); const val = f.air.value(inst).?; try w.writeAll("(*"); - try f.object.dg.renderValue(w, ty, val); + try f.object.dg.renderValue(w, ty, val, .Other); return w.writeByte(')'); }, else => return f.object.dg.writeCValueDeref(w, c_value), @@ -384,7 +389,7 @@ pub const DeclGen = struct { try dg.renderTypecast(writer, ty); try writer.writeAll("){"); var buf: Type.SlicePtrFieldTypeBuffer = undefined; - try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr()); + try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Other); try writer.writeAll(", "); try writer.print("{d}", .{val.sliceLen(dg.module)}); try writer.writeAll("}"); @@ -544,6 +549,7 @@ pub const DeclGen = struct { writer: anytype, ty: Type, val: Value, + location: ValueRenderLocation, ) error{ OutOfMemory, AnalysisFail }!void { const target = dg.module.getTarget(); if (val.isUndefDeep()) { @@ -636,9 +642,9 @@ pub const DeclGen = struct { try writer.writeByte('('); try dg.renderTypecast(writer, ty); try writer.writeAll("){"); - try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr); + try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, location); try writer.writeAll(", "); - try dg.renderValue(writer, Type.usize, slice.len); + try dg.renderValue(writer, Type.usize, slice.len, location); try writer.writeAll("}"); }, .function => { @@ -670,7 +676,7 @@ pub const DeclGen = struct { try writer.writeByte('{'); const ai = ty.arrayInfo(); if (ai.sentinel) |s| { - try dg.renderValue(writer, ai.elem_type, s); + try dg.renderValue(writer, ai.elem_type, s, location); } try writer.writeByte('}'); }, @@ -680,17 +686,23 @@ pub const DeclGen = struct { defer arena.deinit(); const arena_allocator = arena.allocator(); + if (location == .FunctionArgument) { + try writer.writeByte('('); + try dg.renderTypecast(writer, ty); + try writer.writeByte(')'); + } + try writer.writeByte('{'); const ai = ty.arrayInfo(); var index: usize = 0; while (index < ai.len) : (index += 1) { if (index != 0) try writer.writeAll(","); const elem_val = try val.elemValue(dg.module, arena_allocator, index); - try dg.renderValue(writer, ai.elem_type, elem_val); + try dg.renderValue(writer, ai.elem_type, elem_val, .Other); } if (ai.sentinel) |s| { if (index != 0) try writer.writeAll(","); - try dg.renderValue(writer, ai.elem_type, s); + try dg.renderValue(writer, ai.elem_type, s, .Other); } try writer.writeByte('}'); }, @@ -701,7 +713,7 @@ pub const DeclGen = struct { var opt_buf: Type.Payload.ElemType = undefined; const payload_type = ty.optionalChild(&opt_buf); if (ty.isPtrLikeOptional()) { - return dg.renderValue(writer, payload_type, val); + return dg.renderValue(writer, payload_type, val, location); } if (payload_type.abiSize(target) == 0) { const is_null = val.castTag(.opt_payload) == null; @@ -713,7 +725,7 @@ pub const DeclGen = struct { if (val.castTag(.opt_payload)) |pl| { const payload_val = pl.data; try writer.writeAll(" .is_null = false, .payload = "); - try dg.renderValue(writer, payload_type, payload_val); + try dg.renderValue(writer, payload_type, payload_val, location); try writer.writeAll(" }"); } else { try writer.writeAll(" .is_null = true }"); @@ -740,7 +752,7 @@ pub const DeclGen = struct { if (!payload_type.hasRuntimeBits()) { // We use the error type directly as the type. const err_val = if (val.errorUnionIsPayload()) Value.initTag(.zero) else val; - return dg.renderValue(writer, error_type, err_val); + return dg.renderValue(writer, error_type, err_val, location); } try writer.writeByte('('); @@ -749,11 +761,11 @@ pub const DeclGen = struct { if (val.castTag(.eu_payload)) |pl| { const payload_val = pl.data; try writer.writeAll(" .payload = "); - try dg.renderValue(writer, payload_type, payload_val); + try dg.renderValue(writer, payload_type, payload_val, location); try writer.writeAll(", .error = 0 }"); } else { try writer.writeAll(" .error = "); - try dg.renderValue(writer, error_type, val); + try dg.renderValue(writer, error_type, val, location); try writer.writeAll(" }"); } }, @@ -767,7 +779,7 @@ pub const DeclGen = struct { const enum_full = ty.cast(Type.Payload.EnumFull).?.data; if (enum_full.values.count() != 0) { const tag_val = enum_full.values.keys()[field_index]; - return dg.renderValue(writer, enum_full.tag_ty, tag_val); + return dg.renderValue(writer, enum_full.tag_ty, tag_val, location); } else { return writer.print("{d}", .{field_index}); } @@ -776,7 +788,7 @@ pub const DeclGen = struct { const enum_obj = ty.castTag(.enum_numbered).?.data; if (enum_obj.values.count() != 0) { const tag_val = enum_obj.values.keys()[field_index]; - return dg.renderValue(writer, enum_obj.tag_ty, tag_val); + return dg.renderValue(writer, enum_obj.tag_ty, tag_val, location); } else { return writer.print("{d}", .{field_index}); } @@ -787,7 +799,7 @@ pub const DeclGen = struct { else => { var int_tag_ty_buffer: Type.Payload.Bits = undefined; const int_tag_ty = ty.intTagType(&int_tag_ty_buffer); - return dg.renderValue(writer, int_tag_ty, val); + return dg.renderValue(writer, int_tag_ty, val, location); }, } }, @@ -814,7 +826,7 @@ pub const DeclGen = struct { if (!field_ty.hasRuntimeBits()) continue; if (i != 0) try writer.writeAll(","); - try dg.renderValue(writer, field_ty, field_val); + try dg.renderValue(writer, field_ty, field_val, location); } try writer.writeAll("}"); @@ -831,7 +843,7 @@ pub const DeclGen = struct { if (ty.unionTagType()) |tag_ty| { if (layout.tag_size != 0) { try writer.writeAll(".tag = "); - try dg.renderValue(writer, tag_ty, union_obj.tag); + try dg.renderValue(writer, tag_ty, union_obj.tag, location); try writer.writeAll(", "); } try writer.writeAll(".payload = {"); @@ -842,7 +854,7 @@ pub const DeclGen = struct { const field_name = ty.unionFields().keys()[index]; if (field_ty.hasRuntimeBits()) { try writer.print(".{ } = ", .{fmtIdent(field_name)}); - try dg.renderValue(writer, field_ty, union_obj.val); + try dg.renderValue(writer, field_ty, union_obj.val, location); } if (ty.unionTagType()) |_| { try writer.writeAll("}"); @@ -988,7 +1000,7 @@ pub const DeclGen = struct { } if (ptr_sentinel) |s| { try bw.writeAll("_s_"); - try dg.renderValue(bw, child_type, s); + try dg.renderValue(bw, child_type, s, .Other); } try bw.writeAll(";\n"); @@ -1629,7 +1641,7 @@ pub fn genDecl(o: *Object) !void { try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align"); try w.writeAll(" = "); if (variable.init.tag() != .unreachable_value) { - try o.dg.renderValue(w, tv.ty, variable.init); + try o.dg.renderValue(w, tv.ty, variable.init, .Other); } try w.writeAll(";"); try o.indent_writer.insertNewline(); @@ -1644,7 +1656,7 @@ pub fn genDecl(o: *Object) !void { try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align"); try writer.writeAll(" = "); - try o.dg.renderValue(writer, tv.ty, tv.val); + try o.dg.renderValue(writer, tv.ty, tv.val, .Other); try writer.writeAll(";\n"); } } @@ -2748,7 +2760,7 @@ fn airCall( try writer.writeAll(", "); } if (f.air.value(arg)) |val| { - try f.object.dg.renderValue(writer, f.air.typeOf(arg), val); + try f.object.dg.renderValue(writer, f.air.typeOf(arg), val, .FunctionArgument); } else { const val = try f.resolveInst(arg); try f.writeCValue(writer, val); @@ -2964,7 +2976,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { for (items) |item| { try f.object.indent_writer.insertNewline(); try writer.writeAll("case "); - try f.object.dg.renderValue(writer, condition_ty, f.air.value(item).?); + try f.object.dg.renderValue(writer, condition_ty, f.air.value(item).?, .Other); try writer.writeAll(": "); } // The case body must be noreturn so we don't need to insert a break. @@ -3414,14 +3426,14 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { try f.writeCValueDeref(writer, operand); try writer.writeAll(" = "); - try f.object.dg.renderValue(writer, error_ty, Value.zero); + try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other); try writer.writeAll(";\n "); return operand; } try f.writeCValueDeref(writer, operand); try writer.writeAll(".error = "); - try f.object.dg.renderValue(writer, error_ty, Value.zero); + try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other); try writer.writeAll(";\n"); // Then return the payload pointer (only if it is used) diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 13a4763a91..bf5e74e819 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -148,7 +148,7 @@ test "void arrays" { try expect(array.len == 4); } -test "nested arrays" { +test "nested arrays of strings" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; @@ -162,6 +162,22 @@ test "nested arrays" { } } +test "nested arrays of integers" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + + const array_of_numbers = [_][2]u8{ + [2]u8{ 1, 2 }, + [2]u8{ 3, 4 }, + }; + + try expect(array_of_numbers[0][0] == 1); + try expect(array_of_numbers[0][1] == 2); + try expect(array_of_numbers[1][0] == 3); + try expect(array_of_numbers[1][1] == 4); +} + test "implicit comptime in array type size" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index 7d02229ff4..eabb6c77f4 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -349,7 +349,6 @@ fn numberLiteralArg(a: anytype) !void { } test "function call with anon list literal" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; @@ -364,9 +363,19 @@ test "function call with anon list literal" { try expect(vec[1] == 8); try expect(vec[2] == 7); } + + fn doThe2DTest() !void { + try consume2DVec(.{ .{ 9, 8 }, .{ 7, 6 } }); + } + + fn consume2DVec(vec: [2][2]f32) !void { + _ = vec; + } }; try S.doTheTest(); comptime try S.doTheTest(); + try S.doThe2DTest(); + comptime try S.doThe2DTest(); } test "ability to give comptime types and non comptime types to same parameter" { -- cgit v1.2.3 From 0e830b16306945ffc74ef95198eb74743ab9f184 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 22 Apr 2022 07:52:21 -0700 Subject: clean up behavior tests Split big test into the two separate things it is testing. Add missing checks to the test which revealed the test is not actually passing yet for the C backend. --- test/behavior/array.zig | 6 +++--- test/behavior/fn.zig | 30 +++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 12 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/test/behavior/array.zig b/test/behavior/array.zig index bf5e74e819..728e05271a 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -163,9 +163,9 @@ test "nested arrays of strings" { } test "nested arrays of integers" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO const array_of_numbers = [_][2]u8{ [2]u8{ 1, 2 }, diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index eabb6c77f4..26185f6ac1 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -349,9 +349,9 @@ fn numberLiteralArg(a: anytype) !void { } test "function call with anon list literal" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -363,19 +363,31 @@ test "function call with anon list literal" { try expect(vec[1] == 8); try expect(vec[2] == 7); } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "function call with anon list literal - 2D" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - fn doThe2DTest() !void { - try consume2DVec(.{ .{ 9, 8 }, .{ 7, 6 } }); + const S = struct { + fn doTheTest() !void { + try consumeVec(.{ .{ 9, 8 }, .{ 7, 6 } }); } - fn consume2DVec(vec: [2][2]f32) !void { - _ = vec; + fn consumeVec(vec: [2][2]f32) !void { + try expect(vec[0][0] == 9); + try expect(vec[0][1] == 8); + try expect(vec[1][0] == 7); + try expect(vec[1][1] == 6); } }; try S.doTheTest(); comptime try S.doTheTest(); - try S.doThe2DTest(); - comptime try S.doThe2DTest(); } test "ability to give comptime types and non comptime types to same parameter" { -- cgit v1.2.3 From ddd5b57045d38b7d1f7d5a4120302797433233cd Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Thu, 26 May 2022 16:03:49 +0200 Subject: stage2 AArch64: complete genTypedValue --- src/arch/aarch64/CodeGen.zig | 36 ++++++++++++++++++------------------ test/behavior/align.zig | 1 - test/behavior/array.zig | 4 ---- test/behavior/basic.zig | 3 --- test/behavior/bitcast.zig | 1 - test/behavior/bitreverse.zig | 1 - test/behavior/bugs/11165.zig | 2 -- test/behavior/bugs/11181.zig | 2 -- test/behavior/bugs/11213.zig | 1 - test/behavior/bugs/1421.zig | 1 - test/behavior/bugs/394.zig | 1 - test/behavior/bugs/4560.zig | 2 -- test/behavior/bugs/7187.zig | 1 - test/behavior/byteswap.zig | 1 - test/behavior/cast.zig | 2 -- test/behavior/comptime_memory.zig | 4 ---- test/behavior/error.zig | 1 - test/behavior/eval.zig | 7 ------- test/behavior/fn.zig | 9 --------- test/behavior/fn_delegation.zig | 1 - test/behavior/generics.zig | 1 - test/behavior/optional.zig | 2 -- test/behavior/pointers.zig | 2 -- test/behavior/sizeof_and_typeof.zig | 1 - test/behavior/slice.zig | 2 -- test/behavior/struct.zig | 4 ---- test/behavior/type.zig | 2 -- test/behavior/type_info.zig | 1 - test/behavior/union.zig | 1 - test/behavior/void.zig | 2 -- 30 files changed, 18 insertions(+), 81 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index e0c36e70f9..1671f705c7 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -4572,6 +4572,7 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { } fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { + log.debug("genTypedValue: ty = {}, val = {}", .{ typed_value.ty.fmtDebug(), typed_value.val.fmtDebug() }); if (typed_value.val.isUndef()) return MCValue{ .undef = {} }; @@ -4585,20 +4586,13 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { switch (typed_value.ty.zigTypeTag()) { .Pointer => switch (typed_value.ty.ptrSize()) { - .Slice => { - return self.lowerUnnamedConst(typed_value); - }, + .Slice => {}, else => { switch (typed_value.val.tag()) { .int_u64 => { return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) }; }, - .slice => { - return self.lowerUnnamedConst(typed_value); - }, - else => { - return self.fail("TODO codegen more kinds of const pointers: {}", .{typed_value.val.tag()}); - }, + else => {}, } }, }, @@ -4614,15 +4608,11 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { }; return MCValue{ .immediate = unsigned }; - } else { - return self.lowerUnnamedConst(typed_value); } }, .Bool => { return MCValue{ .immediate = @boolToInt(typed_value.val.toBool()) }; }, - .ComptimeInt => unreachable, // semantic analysis prevents this - .ComptimeFloat => unreachable, // semantic analysis prevents this .Optional => { if (typed_value.ty.isPtrLikeOptional()) { if (typed_value.val.isNull()) @@ -4636,7 +4626,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { } else if (typed_value.ty.abiSize(self.target.*) == 1) { return MCValue{ .immediate = @boolToInt(typed_value.val.isNull()) }; } - return self.fail("TODO non pointer optionals", .{}); }, .Enum => { if (typed_value.val.castTag(.enum_field_index)) |field_index| { @@ -4695,11 +4684,22 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { return self.lowerUnnamedConst(typed_value); }, - .Struct => { - return self.lowerUnnamedConst(typed_value); - }, - else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty.fmtDebug()}), + + .ComptimeInt => unreachable, // semantic analysis prevents this + .ComptimeFloat => unreachable, // semantic analysis prevents this + .Type => unreachable, + .EnumLiteral => unreachable, + .Void => unreachable, + .NoReturn => unreachable, + .Undefined => unreachable, + .Null => unreachable, + .BoundFn => unreachable, + .Opaque => unreachable, + + else => {}, } + + return self.lowerUnnamedConst(typed_value); } const CallMCValues = struct { diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 6a819b4a7d..2c0893074e 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -7,7 +7,6 @@ var foo: u8 align(4) = 100; test "global variable alignment" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 728e05271a..93de42df67 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -95,8 +95,6 @@ test "array literal with specified size" { } test "array len field" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var arr = [4]u8{ 0, 0, 0, 0 }; var ptr = &arr; try expect(arr.len == 4); @@ -217,8 +215,6 @@ fn doSomeMangling(array: *[4]u8) void { } test "implicit cast zero sized array ptr to slice" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - { var b = "".*; const c: []const u8 = &b; diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index adcba8721d..ac9e776c76 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -362,7 +362,6 @@ fn testMemcpyMemset() !void { } test "variable is allowed to be a pointer to an opaque type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -611,7 +610,6 @@ test "self reference through fn ptr field" { } test "global variable initialized to global variable array element" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try expect(global_ptr == &gdt[0]); @@ -677,7 +675,6 @@ test "explicit cast optional pointers" { } test "pointer comparison" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index c571851fe4..e851d7de09 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -7,7 +7,6 @@ const minInt = std.math.minInt; const native_endian = builtin.target.cpu.arch.endian(); test "@bitCast iX -> uX (32, 64)" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const bit_values = [_]usize{ 32, 64 }; diff --git a/test/behavior/bitreverse.zig b/test/behavior/bitreverse.zig index 36a3d3475c..821bc21f27 100644 --- a/test/behavior/bitreverse.zig +++ b/test/behavior/bitreverse.zig @@ -158,7 +158,6 @@ test "bitReverse vectors u0" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; comptime try vector0(); try vector0(); diff --git a/test/behavior/bugs/11165.zig b/test/behavior/bugs/11165.zig index cf2f9698f9..b3c4a32ec4 100644 --- a/test/behavior/bugs/11165.zig +++ b/test/behavior/bugs/11165.zig @@ -2,7 +2,6 @@ const builtin = @import("builtin"); test "bytes" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { a: u32, @@ -25,7 +24,6 @@ test "bytes" { test "aggregate" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { a: u32, diff --git a/test/behavior/bugs/11181.zig b/test/behavior/bugs/11181.zig index 738bd4e3e7..67d26d6b4e 100644 --- a/test/behavior/bugs/11181.zig +++ b/test/behavior/bugs/11181.zig @@ -2,7 +2,6 @@ const builtin = @import("builtin"); test "const inferred array of slices" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const T = struct { v: bool }; @@ -16,7 +15,6 @@ test "const inferred array of slices" { test "var inferred array of slices" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const T = struct { v: bool }; diff --git a/test/behavior/bugs/11213.zig b/test/behavior/bugs/11213.zig index d4e3580c07..f238eb5aab 100644 --- a/test/behavior/bugs/11213.zig +++ b/test/behavior/bugs/11213.zig @@ -4,7 +4,6 @@ const testing = std.testing; test { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const g: error{Test}!void = error.Test; diff --git a/test/behavior/bugs/1421.zig b/test/behavior/bugs/1421.zig index e4e42bd21b..d6ea8a2bad 100644 --- a/test/behavior/bugs/1421.zig +++ b/test/behavior/bugs/1421.zig @@ -9,7 +9,6 @@ const S = struct { }; test "functions with return type required to be comptime are generic" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; const ti = S.method(); diff --git a/test/behavior/bugs/394.zig b/test/behavior/bugs/394.zig index e7d6e80936..9f5165d1ba 100644 --- a/test/behavior/bugs/394.zig +++ b/test/behavior/bugs/394.zig @@ -11,7 +11,6 @@ const expect = @import("std").testing.expect; const builtin = @import("builtin"); test "fixed" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const x = S{ diff --git a/test/behavior/bugs/4560.zig b/test/behavior/bugs/4560.zig index 30d3677920..ea40e55da3 100644 --- a/test/behavior/bugs/4560.zig +++ b/test/behavior/bugs/4560.zig @@ -2,8 +2,6 @@ const std = @import("std"); const builtin = @import("builtin"); test "fixed" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var s: S = .{ .a = 1, .b = .{ diff --git a/test/behavior/bugs/7187.zig b/test/behavior/bugs/7187.zig index 86f5aa6706..9ce63ad4cd 100644 --- a/test/behavior/bugs/7187.zig +++ b/test/behavior/bugs/7187.zig @@ -3,7 +3,6 @@ const builtin = @import("builtin"); const expect = std.testing.expect; test "miscompilation with bool return type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var x: usize = 1; diff --git a/test/behavior/byteswap.zig b/test/behavior/byteswap.zig index 6e317b7fc2..13cc823e9d 100644 --- a/test/behavior/byteswap.zig +++ b/test/behavior/byteswap.zig @@ -118,7 +118,6 @@ test "@byteSwap vectors u0" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; comptime try vector0(); try vector0(); diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 58b458ad1e..4ff2c78d47 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -843,7 +843,6 @@ test "peer cast *[0]T to []const T" { } test "peer cast *[N]T to [*]T" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO var array = [4:99]i32{ 1, 2, 3, 4 }; @@ -1116,7 +1115,6 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void { test "compile time int to ptr of function" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO diff --git a/test/behavior/comptime_memory.zig b/test/behavior/comptime_memory.zig index 17cee27771..1a3e9ef606 100644 --- a/test/behavior/comptime_memory.zig +++ b/test/behavior/comptime_memory.zig @@ -5,7 +5,6 @@ const ptr_size = @sizeOf(usize); test "type pun signed and unsigned as single pointer" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO comptime { @@ -18,7 +17,6 @@ test "type pun signed and unsigned as single pointer" { test "type pun signed and unsigned as many pointer" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO comptime { var x: u32 = 0; @@ -30,7 +28,6 @@ test "type pun signed and unsigned as many pointer" { test "type pun signed and unsigned as array pointer" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO comptime { var x: u32 = 0; @@ -74,7 +71,6 @@ test "type pun signed and unsigned as array pointer" { test "type pun value and struct" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO comptime { const StructOfU32 = extern struct { x: u32 }; diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 312ab1524a..b735d70d73 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -119,7 +119,6 @@ test "widen cast integer payload of error union function call" { test "debug info for optional error set" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const SomeError = error{ Hello, Hello2 }; var a_local_variable: ?SomeError = null; diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 4609b58ddb..f14a25451d 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -406,8 +406,6 @@ var st_init_str_foo = StInitStrFoo{ }; test "inline for with same type but different values" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - var res: usize = 0; inline for ([_]type{ [2]u8, [1]u8, [2]u8 }) |T| { var a: T = undefined; @@ -487,7 +485,6 @@ test "comptime bitwise operators" { test "comptime shlWithOverflow" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const ct_shifted: u64 = comptime amt: { var amt = @as(u64, 0); @@ -559,8 +556,6 @@ pub fn vec3(x: f32, y: f32, z: f32) Vec3 { } test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - var runtime = [1]i32{3}; comptime var i: usize = 0; inline while (i < 2) : (i += 1) { @@ -611,7 +606,6 @@ const hi1 = "hi"; const hi2 = hi1; test "const global shares pointer with other same one" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try assertEqualPtrs(&hi1[0], &hi2[0]); comptime try expect(&hi1[0] == &hi2[0]); @@ -982,7 +976,6 @@ test "closure capture type of runtime-known parameter" { test "comptime break passing through runtime condition converted to runtime break" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index 26185f6ac1..324a2ad247 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -184,8 +184,6 @@ test "function with complex callconv and return type expressions" { } test "pass by non-copying value" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - try expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3); } @@ -211,8 +209,6 @@ fn addPointCoordsVar(pt: anytype) !i32 { } test "pass by non-copying value as method" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var pt = Point2{ .x = 1, .y = 2 }; try expect(pt.addPointCoords() == 3); } @@ -227,8 +223,6 @@ const Point2 = struct { }; test "pass by non-copying value as method, which is generic" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var pt = Point3{ .x = 1, .y = 2 }; try expect(pt.addPointCoords(i32) == 3); } @@ -244,8 +238,6 @@ const Point3 = struct { }; test "pass by non-copying value as method, at comptime" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - comptime { var pt = Point2{ .x = 1, .y = 2 }; try expect(pt.addPointCoords() == 3); @@ -409,7 +401,6 @@ test "ability to give comptime types and non comptime types to same parameter" { test "function with inferred error set but returning no error" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { fn foo() !void {} diff --git a/test/behavior/fn_delegation.zig b/test/behavior/fn_delegation.zig index eee8f52490..25ec3dea1b 100644 --- a/test/behavior/fn_delegation.zig +++ b/test/behavior/fn_delegation.zig @@ -32,7 +32,6 @@ fn custom(comptime T: type, comptime num: u64) fn (T) u64 { } test "fn delegation" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const foo = Foo{}; diff --git a/test/behavior/generics.zig b/test/behavior/generics.zig index 2a18135fe0..cd4e018be3 100644 --- a/test/behavior/generics.zig +++ b/test/behavior/generics.zig @@ -206,7 +206,6 @@ fn foo2(arg: anytype) bool { test "generic struct" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var a1 = GenNode(i32){ .value = 13, .next = null, diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index 6219a6a5be..4e5eb5061c 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -33,8 +33,6 @@ test "optional pointer to size zero struct" { } test "equality compare optional pointers" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - try testNullPtrsEql(); comptime try testNullPtrsEql(); } diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index 07bab40135..a47d931883 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -85,7 +85,6 @@ test "assigning integer to C pointer" { test "C pointer comparison and arithmetic" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const S = struct { fn doTheTest() !void { @@ -477,7 +476,6 @@ test "element pointer arithmetic to slice" { } test "array slicing to slice" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { diff --git a/test/behavior/sizeof_and_typeof.zig b/test/behavior/sizeof_and_typeof.zig index 4421b59f96..6c7e16b502 100644 --- a/test/behavior/sizeof_and_typeof.zig +++ b/test/behavior/sizeof_and_typeof.zig @@ -19,7 +19,6 @@ test "@sizeOf on compile-time types" { test "@TypeOf() with multiple arguments" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; { diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 18c769f27c..e2694759bb 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -207,7 +207,6 @@ test "slice string literal has correct type" { } test "result location zero sized array inside struct field implicit cast to slice" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO const E = struct { @@ -509,7 +508,6 @@ test "slice pointer-to-array null terminated" { test "slice pointer-to-array zero length" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO comptime { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 8370cd763e..5cbb8e973e 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -168,14 +168,12 @@ const MemberFnTestFoo = struct { }; test "call member function directly" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const instance = MemberFnTestFoo{ .x = 1234 }; const result = MemberFnTestFoo.member(instance); try expect(result == 1234); } test "store member function in variable" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const instance = MemberFnTestFoo{ .x = 1234 }; const memberFn = MemberFnTestFoo.member; const result = memberFn(instance); @@ -1000,8 +998,6 @@ test "tuple element initialized with fn call" { } test "struct with union field" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - const Value = struct { ref: u32 = 2, kind: union(enum) { diff --git a/test/behavior/type.zig b/test/behavior/type.zig index c543d4f969..f4a32e5df0 100644 --- a/test/behavior/type.zig +++ b/test/behavior/type.zig @@ -473,7 +473,6 @@ test "Type.Union" { test "Type.Union from Type.Enum" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const Tag = @Type(.{ .Enum = .{ @@ -503,7 +502,6 @@ test "Type.Union from Type.Enum" { test "Type.Union from regular enum" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const E = enum { working_as_expected }; const T = @Type(.{ diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index 32b9671f96..7bbfbbc1ab 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -381,7 +381,6 @@ extern fn foo(a: usize, b: bool, ...) callconv(.C) usize; extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize; test "type info: generic function types" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend != .stage1) { diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 7f17ff50c6..4daa9c1ee5 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -1111,7 +1111,6 @@ test "union enum type gets a separate scope" { test "global variable struct contains union initialized to non-most-aligned field" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const T = struct { const U = union(enum) { diff --git a/test/behavior/void.zig b/test/behavior/void.zig index fc1972c506..66b969d0bf 100644 --- a/test/behavior/void.zig +++ b/test/behavior/void.zig @@ -42,8 +42,6 @@ test "void optional" { } test "void array as a local variable initializer" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - var x = [_]void{{}} ** 1004; _ = x[0]; } -- cgit v1.2.3 From 2b93546b39a85e9316c2bf12f336c357577114fa Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Fri, 3 Jun 2022 16:10:18 +0300 Subject: Sema: fix initialization of array with comptime only elem type --- src/Sema.zig | 20 +++++++++++--------- test/behavior/array.zig | 9 +++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/Sema.zig b/src/Sema.zig index 05ce2adb77..d3ca6a8cc5 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -3598,7 +3598,7 @@ fn zirValidateArrayInit( // any ZIR instructions at comptime; we need to do that here. if (array_ty.sentinel()) |sentinel_val| { const array_len_ref = try sema.addIntUnsigned(Type.usize, array_len); - const sentinel_ptr = try sema.elemPtrArray(block, init_src, array_ptr, init_src, array_len_ref); + const sentinel_ptr = try sema.elemPtrArray(block, init_src, array_ptr, init_src, array_len_ref, true); const sentinel = try sema.addConstant(array_ty.childType(), sentinel_val); try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store); } @@ -7540,7 +7540,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const bin_inst = sema.code.instructions.items(.data)[inst].bin; const array_ptr = try sema.resolveInst(bin_inst.lhs); const elem_index = try sema.resolveInst(bin_inst.rhs); - return sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src); + return sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src, false); } fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -7553,7 +7553,7 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; const array_ptr = try sema.resolveInst(extra.lhs); const elem_index = try sema.resolveInst(extra.rhs); - return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src); + return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src, false); } fn zirElemPtrImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -7565,7 +7565,7 @@ fn zirElemPtrImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data; const array_ptr = try sema.resolveInst(extra.ptr); const elem_index = try sema.addIntUnsigned(Type.usize, extra.index); - return sema.elemPtr(block, src, array_ptr, elem_index, src); + return sema.elemPtr(block, src, array_ptr, elem_index, src, true); } fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -18724,6 +18724,7 @@ fn elemPtr( indexable_ptr: Air.Inst.Ref, elem_index: Air.Inst.Ref, elem_index_src: LazySrcLoc, + init: bool, ) CompileError!Air.Inst.Ref { const indexable_ptr_src = src; // TODO better source location const indexable_ptr_ty = sema.typeOf(indexable_ptr); @@ -18760,11 +18761,11 @@ fn elemPtr( }, .One => { assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable - return sema.elemPtrArray(block, indexable_ptr_src, indexable, elem_index_src, elem_index); + return sema.elemPtrArray(block, indexable_ptr_src, indexable, elem_index_src, elem_index, init); }, } }, - .Array, .Vector => return sema.elemPtrArray(block, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index), + .Array, .Vector => return sema.elemPtrArray(block, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init), .Struct => { // Tuple field access. const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index); @@ -18818,7 +18819,7 @@ fn elemVal( }, .One => { assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable - const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src); + const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false); return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src); }, }, @@ -18999,6 +19000,7 @@ fn elemPtrArray( array_ptr: Air.Inst.Ref, elem_index_src: LazySrcLoc, elem_index: Air.Inst.Ref, + init: bool, ) CompileError!Air.Inst.Ref { const target = sema.mod.getTarget(); const array_ptr_ty = sema.typeOf(array_ptr); @@ -19035,7 +19037,7 @@ fn elemPtrArray( } const valid_rt = try sema.validateRunTimeType(block, elem_index_src, array_ty.elemType2(), false); - if (!valid_rt) { + if (!valid_rt and !init) { const msg = msg: { const msg = try sema.errMsg( block, @@ -20138,7 +20140,7 @@ fn storePtr2( const elem_src = operand_src; // TODO better source location const elem = try tupleField(sema, block, operand_src, uncasted_operand, elem_src, i); const elem_index = try sema.addIntUnsigned(Type.usize, i); - const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src); + const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src, false); try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store); } return; diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 93de42df67..bccff1edf0 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -573,3 +573,12 @@ test "type coercion of pointer to anon struct literal to pointer to array" { try S.doTheTest(); comptime try S.doTheTest(); } + +test "array with comptime only element type" { + const a = [_]type{ + u32, + i32, + }; + try testing.expect(a[0] == u32); + try testing.expect(a[1] == i32); +} -- cgit v1.2.3 From b9dcbe6b4c0bee37b31bf46424f284af331d4696 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Wed, 15 Jun 2022 18:00:29 +0300 Subject: Sema: handle sentinels in tupleToArray --- src/Sema.zig | 12 +++++++++--- test/behavior/array.zig | 11 +++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/Sema.zig b/src/Sema.zig index af3e824855..1d5342b841 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -21793,7 +21793,7 @@ fn coerceTupleToArray( ) !Air.Inst.Ref { const inst_ty = sema.typeOf(inst); const inst_len = inst_ty.arrayLen(); - const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen()); + const dest_len = dest_ty.arrayLen(); if (dest_len != inst_len) { const msg = msg: { @@ -21808,13 +21808,19 @@ fn coerceTupleToArray( return sema.failWithOwnedErrorMsg(block, msg); } - const element_vals = try sema.arena.alloc(Value, dest_len); - const element_refs = try sema.arena.alloc(Air.Inst.Ref, dest_len); + const dest_elems = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLenIncludingSentinel()); + const element_vals = try sema.arena.alloc(Value, dest_elems); + const element_refs = try sema.arena.alloc(Air.Inst.Ref, dest_elems); const dest_elem_ty = dest_ty.childType(); var runtime_src: ?LazySrcLoc = null; for (element_vals) |*elem, i_usize| { const i = @intCast(u32, i_usize); + if (i_usize == inst_len) { + elem.* = dest_ty.sentinel().?; + element_refs[i] = try sema.addConstant(dest_elem_ty, elem.*); + break; + } const elem_src = inst_src; // TODO better source location const elem_ref = try tupleField(sema, block, inst_src, inst, elem_src, i); const coerced = try sema.coerce(block, dest_elem_ty, elem_ref, elem_src); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index bccff1edf0..6482bfa1fe 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -582,3 +582,14 @@ test "array with comptime only element type" { try testing.expect(a[0] == u32); try testing.expect(a[1] == i32); } + +test "tuple to array handles sentinel" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + const a = .{ 1, 2, 3 }; + var b: [3:0]u8 = a; + }; + try expect(S.b[0] == 1); +} -- cgit v1.2.3 From 672d6df42900b8521597c58af64a723985bbfd36 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Thu, 16 Jun 2022 01:31:49 +0700 Subject: stage2: sparc64: Skip Sema-failing tests for now --- test/behavior/array.zig | 1 + test/behavior/atomics.zig | 13 +++++++++++++ test/behavior/basic.zig | 5 +++++ test/behavior/bugs/9584.zig | 1 + test/behavior/byteswap.zig | 1 + 5 files changed, 21 insertions(+) (limited to 'test/behavior/array.zig') diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 6482bfa1fe..59f2baf5b6 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -511,6 +511,7 @@ test "zero-sized array with recursive type definition" { test "type coercion of anon struct literal to array" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/atomics.zig b/test/behavior/atomics.zig index 62471c5ea0..1495ac75a4 100644 --- a/test/behavior/atomics.zig +++ b/test/behavior/atomics.zig @@ -8,6 +8,7 @@ test "cmpxchg" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testCmpxchg(); @@ -48,6 +49,7 @@ test "atomicrmw and atomicload" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var data: u8 = 200; @@ -77,6 +79,7 @@ test "cmpxchg with ptr" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var data1: i32 = 1234; @@ -103,6 +106,7 @@ test "cmpxchg with ignored result" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var x: i32 = 1234; @@ -117,6 +121,7 @@ test "128-bit cmpxchg" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.cpu.arch != .x86_64) return error.SkipZigTest; @@ -150,6 +155,7 @@ test "cmpxchg on a global variable" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if ((builtin.zig_backend == .stage1 or builtin.zig_backend == .stage2_llvm) and @@ -168,6 +174,7 @@ test "atomic load and rmw with enum" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const Value = enum(u8) { a, b, c }; @@ -186,6 +193,7 @@ test "atomic store" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var x: u32 = 0; @@ -200,6 +208,7 @@ test "atomic store comptime" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO comptime try testAtomicStore(); @@ -219,6 +228,7 @@ test "atomicrmw with floats" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if ((builtin.zig_backend == .stage1 or builtin.zig_backend == .stage2_llvm) and @@ -247,6 +257,7 @@ test "atomicrmw with ints" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testAtomicRmwInt(); @@ -281,6 +292,7 @@ test "atomics with different types" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testAtomicsWithType(bool, true, false); @@ -311,6 +323,7 @@ test "return @atomicStore, using it as a void value" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index ac9d90d5e6..ad403a60a8 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -24,6 +24,8 @@ fn testTruncate(x: u32) u8 { } test "truncate to non-power-of-two integers" { + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + try testTrunc(u32, u1, 0b10101, 0b1); try testTrunc(u32, u1, 0b10110, 0b0); try testTrunc(u32, u2, 0b10101, 0b01); @@ -401,6 +403,7 @@ fn testPointerToVoidReturnType2() *const void { test "array 2D const double ptr" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO @@ -414,6 +417,7 @@ test "array 2D const double ptr" { test "array 2D const double ptr with offset" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; @@ -427,6 +431,7 @@ test "array 2D const double ptr with offset" { test "array 3D const double ptr with offset" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO diff --git a/test/behavior/bugs/9584.zig b/test/behavior/bugs/9584.zig index 487f6ca41c..709d510072 100644 --- a/test/behavior/bugs/9584.zig +++ b/test/behavior/bugs/9584.zig @@ -46,6 +46,7 @@ test { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO diff --git a/test/behavior/byteswap.zig b/test/behavior/byteswap.zig index 13cc823e9d..f944c731b7 100644 --- a/test/behavior/byteswap.zig +++ b/test/behavior/byteswap.zig @@ -7,6 +7,7 @@ test "@byteSwap integers" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; const ByteSwapIntTest = struct { fn run() !void { -- cgit v1.2.3 From 960c14206094484cee056b8806b9b8f75a84891d Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Sat, 25 Jun 2022 14:59:22 +0200 Subject: stage2 ARM: implement basic intCast and error union wrapping --- src/arch/arm/CodeGen.zig | 66 ++++++++++++++++++----- test/behavior/align.zig | 2 - test/behavior/array.zig | 6 --- test/behavior/basic.zig | 9 ---- test/behavior/bitreverse.zig | 1 - test/behavior/bugs/1076.zig | 1 - test/behavior/bugs/11165.zig | 4 -- test/behavior/bugs/11213.zig | 1 - test/behavior/bugs/3779.zig | 5 -- test/behavior/bugs/394.zig | 1 - test/behavior/bugs/7187.zig | 2 - test/behavior/byteswap.zig | 1 - test/behavior/byval_arg_var.zig | 1 - test/behavior/cast.zig | 11 ---- test/behavior/comptime_memory.zig | 1 - test/behavior/enum.zig | 1 - test/behavior/error.zig | 13 ----- test/behavior/eval.zig | 8 --- test/behavior/fn.zig | 1 - test/behavior/if.zig | 1 - test/behavior/math.zig | 3 -- test/behavior/pointers.zig | 5 -- test/behavior/reflection.zig | 1 - test/behavior/slice.zig | 5 -- test/behavior/struct_contains_slice_of_itself.zig | 2 - test/behavior/tuple.zig | 1 - test/behavior/type_info.zig | 2 - test/behavior/union.zig | 7 --- test/behavior/var_args.zig | 1 - test/behavior/while.zig | 2 - test/behavior/widening.zig | 1 - 31 files changed, 53 insertions(+), 113 deletions(-) (limited to 'test/behavior/array.zig') diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 3cc853154b..9a93969209 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -1002,18 +1002,35 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); - const operand_ty = self.air.typeOf(ty_op.operand); const operand = try self.resolveInst(ty_op.operand); + const operand_ty = self.air.typeOf(ty_op.operand); + const dest_ty = self.air.typeOfIndex(inst); + + const operand_abi_size = operand_ty.abiSize(self.target.*); + const dest_abi_size = dest_ty.abiSize(self.target.*); const info_a = operand_ty.intInfo(self.target.*); - const info_b = self.air.typeOfIndex(inst).intInfo(self.target.*); - if (info_a.signedness != info_b.signedness) - return self.fail("TODO gen intcast sign safety in semantic analysis", .{}); + const info_b = dest_ty.intInfo(self.target.*); + + const dst_mcv: MCValue = blk: { + if (info_a.bits == info_b.bits) { + break :blk operand; + } + if (operand_abi_size > 4 or dest_abi_size > 4) { + return self.fail("TODO implement intCast for abi sizes larger than 4", .{}); + } + + const operand_lock: ?RegisterLock = switch (operand) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); - if (info_a.bits == info_b.bits) - return self.finishAir(inst, operand, .{ ty_op.operand, .none, .none }); + const reg = try self.register_manager.allocReg(inst, gp); + try self.genSetReg(dest_ty, reg, operand); + break :blk MCValue{ .register = reg }; + }; - return self.fail("TODO implement intCast for {}", .{self.target.cpu.arch}); - // return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); + return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); } fn truncRegister( @@ -1880,7 +1897,22 @@ fn airSetErrReturnTrace(self: *Self, inst: Air.Inst.Index) !void { /// T to E!T fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement wrap errunion payload for {}", .{self.target.cpu.arch}); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { + const error_union_ty = self.air.getRefType(ty_op.ty); + const payload_ty = error_union_ty.errorUnionPayload(); + const operand = try self.resolveInst(ty_op.operand); + if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result operand; + + const abi_size = @intCast(u32, error_union_ty.abiSize(self.target.*)); + const abi_align = error_union_ty.abiAlignment(self.target.*); + const stack_offset = @intCast(u32, try self.allocMem(inst, abi_size, abi_align)); + const payload_off = errUnionPayloadOffset(payload_ty, self.target.*); + const err_off = errUnionErrorOffset(payload_ty, self.target.*); + try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), operand); + try self.genSetStack(Type.anyerror, stack_offset - @intCast(u32, err_off), .{ .immediate = 0 }); + + break :result MCValue{ .stack_offset = stack_offset }; + }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -1890,10 +1922,18 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const error_union_ty = self.air.getRefType(ty_op.ty); const payload_ty = error_union_ty.errorUnionPayload(); - const mcv = try self.resolveInst(ty_op.operand); - if (!payload_ty.hasRuntimeBits()) break :result mcv; + const operand = try self.resolveInst(ty_op.operand); + if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result operand; + + const abi_size = @intCast(u32, error_union_ty.abiSize(self.target.*)); + const abi_align = error_union_ty.abiAlignment(self.target.*); + const stack_offset = @intCast(u32, try self.allocMem(inst, abi_size, abi_align)); + const payload_off = errUnionPayloadOffset(payload_ty, self.target.*); + const err_off = errUnionErrorOffset(payload_ty, self.target.*); + try self.genSetStack(Type.anyerror, stack_offset - @intCast(u32, err_off), operand); + try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), .undef); - return self.fail("TODO implement wrap errunion error for non-empty payloads", .{}); + break :result MCValue{ .stack_offset = stack_offset }; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -4273,7 +4313,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { block_data.mcv = switch (operand_mcv) { .none, .dead, .unreach => unreachable, .register, .stack_offset, .memory => operand_mcv, - .immediate, .stack_argument_offset => blk: { + .immediate, .stack_argument_offset, .cpsr_flags => blk: { const new_mcv = try self.allocRegOrMem(block, true); try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv); break :blk new_mcv; diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 056354f237..b0df7c6523 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -8,7 +8,6 @@ var foo: u8 align(4) = 100; test "global variable alignment" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); comptime try expect(@TypeOf(&foo) == *align(4) u8); @@ -223,7 +222,6 @@ fn testBytesAlign(b: u8) !void { test "@alignCast slices" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array align(4) = [_]u32{ 1, 1 }; const slice = array[0..]; diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 59f2baf5b6..aea4dd357b 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -59,7 +59,6 @@ test "array init with mult" { test "array literal with explicit type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const hex_mult: [4]u16 = .{ 4096, 256, 16, 1 }; @@ -112,7 +111,6 @@ test "array with sentinels" { } if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest(is_ct: bool) !void { @@ -162,7 +160,6 @@ test "nested arrays of strings" { test "nested arrays of integers" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO const array_of_numbers = [_][2]u8{ @@ -190,7 +187,6 @@ fn plusOne(x: u32) u32 { test "single-item pointer to array indexing and slicing" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try testSingleItemPtrArrayIndexSlice(); comptime try testSingleItemPtrArrayIndexSlice(); @@ -313,7 +309,6 @@ test "comptime evaluating function that takes array by value" { test "runtime initialize array elem and then implicit cast to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var two: i32 = 2; const x: []const i32 = &[_]i32{two}; @@ -322,7 +317,6 @@ test "runtime initialize array elem and then implicit cast to slice" { test "array literal as argument to function" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn entry(two: i32) !void { diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index ad403a60a8..d288d35787 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -204,7 +204,6 @@ test "opaque types" { } if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try expect(*OpaqueA != *OpaqueB); @@ -365,7 +364,6 @@ fn testMemcpyMemset() !void { } test "variable is allowed to be a pointer to an opaque type" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO var x: i32 = 1234; @@ -457,7 +455,6 @@ fn testArray2DConstDoublePtr(ptr: *const f32) !void { test "double implicit cast in same expression" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var x = @as(i32, @as(u16, nine())); try expect(x == 9); @@ -616,8 +613,6 @@ test "self reference through fn ptr field" { } test "global variable initialized to global variable array element" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - try expect(global_ptr == &gdt[0]); } const GDTEntry = struct { @@ -681,7 +676,6 @@ test "explicit cast optional pointers" { } test "pointer comparison" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const a = @as([]const u8, "a"); @@ -787,7 +781,6 @@ test "pointer to thread local array" { threadlocal var buffer: [11]u8 = undefined; test "auto created variables have correct alignment" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { @@ -889,7 +882,6 @@ test "labeled block implicitly ends in a break" { test "catch in block has correct result location" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn open() error{A}!@This() { @@ -920,7 +912,6 @@ test "labeled block with runtime branch forwards its result location type to bre test "try in labeled block doesn't cast to wrong type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { a: u32, diff --git a/test/behavior/bitreverse.zig b/test/behavior/bitreverse.zig index 821bc21f27..585fe381b0 100644 --- a/test/behavior/bitreverse.zig +++ b/test/behavior/bitreverse.zig @@ -157,7 +157,6 @@ test "bitReverse vectors u0" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; comptime try vector0(); try vector0(); diff --git a/test/behavior/bugs/1076.zig b/test/behavior/bugs/1076.zig index 6bf38eb617..dedf021293 100644 --- a/test/behavior/bugs/1076.zig +++ b/test/behavior/bugs/1076.zig @@ -5,7 +5,6 @@ const expect = std.testing.expect; test "comptime code should not modify constant data" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try testCastPtrOfArrayToSliceAndPtr(); diff --git a/test/behavior/bugs/11165.zig b/test/behavior/bugs/11165.zig index b3c4a32ec4..60677743ad 100644 --- a/test/behavior/bugs/11165.zig +++ b/test/behavior/bugs/11165.zig @@ -1,8 +1,6 @@ const builtin = @import("builtin"); test "bytes" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - const S = struct { a: u32, c: [5]u8, @@ -23,8 +21,6 @@ test "bytes" { } test "aggregate" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - const S = struct { a: u32, c: [5]u8, diff --git a/test/behavior/bugs/11213.zig b/test/behavior/bugs/11213.zig index f238eb5aab..4699bda333 100644 --- a/test/behavior/bugs/11213.zig +++ b/test/behavior/bugs/11213.zig @@ -4,7 +4,6 @@ const testing = std.testing; test { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const g: error{Test}!void = error.Test; diff --git a/test/behavior/bugs/3779.zig b/test/behavior/bugs/3779.zig index 308b26cbcf..dc906442a6 100644 --- a/test/behavior/bugs/3779.zig +++ b/test/behavior/bugs/3779.zig @@ -8,7 +8,6 @@ const ptr_tag_name: [*:0]const u8 = tag_name; test "@tagName() returns a string literal" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; // stage1 gets the type wrong if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try std.testing.expect(*const [13:0]u8 == @TypeOf(tag_name)); try std.testing.expect(std.mem.eql(u8, "TestEnumValue", tag_name)); @@ -22,7 +21,6 @@ const ptr_error_name: [*:0]const u8 = error_name; test "@errorName() returns a string literal" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; // stage1 gets the type wrong if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try std.testing.expect(*const [13:0]u8 == @TypeOf(error_name)); try std.testing.expect(std.mem.eql(u8, "TestErrorCode", error_name)); @@ -36,7 +34,6 @@ const ptr_type_name: [*:0]const u8 = type_name; test "@typeName() returns a string literal" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; // stage1 gets the type wrong if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try std.testing.expect(*const [type_name.len:0]u8 == @TypeOf(type_name)); try std.testing.expect(std.mem.eql(u8, "behavior.bugs.3779.TestType", type_name)); @@ -49,7 +46,6 @@ const expected_contents = "hello zig\n"; test "@embedFile() returns a string literal" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try std.testing.expect(*const [expected_contents.len:0]u8 == @TypeOf(actual_contents)); try std.testing.expect(std.mem.eql(u8, expected_contents, actual_contents)); @@ -63,7 +59,6 @@ fn testFnForSrc() std.builtin.SourceLocation { test "@src() returns a struct containing 0-terminated string slices" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const src = testFnForSrc(); try std.testing.expect([:0]const u8 == @TypeOf(src.file)); diff --git a/test/behavior/bugs/394.zig b/test/behavior/bugs/394.zig index 9f5165d1ba..02e90258bf 100644 --- a/test/behavior/bugs/394.zig +++ b/test/behavior/bugs/394.zig @@ -11,7 +11,6 @@ const expect = @import("std").testing.expect; const builtin = @import("builtin"); test "fixed" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const x = S{ .x = 3, diff --git a/test/behavior/bugs/7187.zig b/test/behavior/bugs/7187.zig index 9ce63ad4cd..bb2e82af89 100644 --- a/test/behavior/bugs/7187.zig +++ b/test/behavior/bugs/7187.zig @@ -3,8 +3,6 @@ const builtin = @import("builtin"); const expect = std.testing.expect; test "miscompilation with bool return type" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - var x: usize = 1; var y: bool = getFalse(); _ = y; diff --git a/test/behavior/byteswap.zig b/test/behavior/byteswap.zig index f944c731b7..263f2c046e 100644 --- a/test/behavior/byteswap.zig +++ b/test/behavior/byteswap.zig @@ -118,7 +118,6 @@ test "@byteSwap vectors u0" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; comptime try vector0(); try vector0(); diff --git a/test/behavior/byval_arg_var.zig b/test/behavior/byval_arg_var.zig index d2e8ecb638..b6b972d2d3 100644 --- a/test/behavior/byval_arg_var.zig +++ b/test/behavior/byval_arg_var.zig @@ -6,7 +6,6 @@ var result: []const u8 = "wrong"; test "pass string literal byvalue to a generic var param" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; start(); blowUpStack(10); diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 383b72e046..c980de8e8a 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -251,7 +251,6 @@ fn MakeType(comptime T: type) type { test "implicit cast from *[N]T to [*c]T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var x: [4]u16 = [4]u16{ 0, 1, 2, 3 }; var y: [*c]u16 = &x; @@ -372,7 +371,6 @@ test "cast from ?[*]T to ??[*]T" { test "peer type unsigned int to signed" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var w: u31 = 5; var x: u8 = 7; @@ -451,7 +449,6 @@ fn castToOptionalTypeError(z: i32) !void { test "implicitly cast from [0]T to anyerror![]T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testCastZeroArrayToErrSliceMut(); comptime try testCastZeroArrayToErrSliceMut(); @@ -817,7 +814,6 @@ test "peer type resolution: error union after non-error" { test "peer cast *[0]T to E![]const T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var buffer: [5]u8 = "abcde".*; @@ -832,7 +828,6 @@ test "peer cast *[0]T to E![]const T" { test "peer cast *[0]T to []const T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var buffer: [5]u8 = "abcde".*; @@ -893,7 +888,6 @@ test "peer cast [:x]T to []T" { test "peer cast [N:x]T to [N]T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -909,7 +903,6 @@ test "peer cast [N:x]T to [N]T" { test "peer cast *[N:x]T to *[N]T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -1146,7 +1139,6 @@ test "implicit ptr to *anyopaque" { test "return null from fn() anyerror!?&T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const a = returnNullFromOptionalTypeErrorRef(); const b = returnNullLitFromOptionalTypeErrorRef(); @@ -1248,7 +1240,6 @@ fn incrementVoidPtrValue(value: ?*anyopaque) void { test "implicit cast *[0]T to E![]const u8" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var x = @as(anyerror![]const u8, &[0]u8{}); try expect((x catch unreachable).len == 0); @@ -1387,7 +1378,6 @@ test "peer type resolution: unreachable, null, slice" { test "cast i8 fn call peers to i32 result" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -1417,7 +1407,6 @@ test "cast compatible optional types" { test "coerce undefined single-item pointer of array to error union of slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const a = @as([*]u8, undefined)[0..0]; var b: error{a}![]const u8 = a; diff --git a/test/behavior/comptime_memory.zig b/test/behavior/comptime_memory.zig index 1a3e9ef606..1fc3f64cda 100644 --- a/test/behavior/comptime_memory.zig +++ b/test/behavior/comptime_memory.zig @@ -5,7 +5,6 @@ const ptr_size = @sizeOf(usize); test "type pun signed and unsigned as single pointer" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO comptime { var x: u32 = 0; diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index e230032d04..602ad47b59 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -24,7 +24,6 @@ fn testIntToEnumEval(x: i32) !void { const IntToEnumNumber = enum { Zero, One, Two, Three, Four }; test "int to enum" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try testIntToEnumEval(3); diff --git a/test/behavior/error.zig b/test/behavior/error.zig index c9697a0f82..c32ca6f6a1 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -29,7 +29,6 @@ fn shouldBeNotEqual(a: anyerror, b: anyerror) void { } test "error binary operator" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const a = errBinaryOperatorG(true) catch 3; @@ -61,14 +60,12 @@ pub fn baz() anyerror!i32 { } test "error wrapping" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect((baz() catch unreachable) == 15); } test "unwrap simple value from error" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const i = unwrapSimpleValueFromErrorDo() catch unreachable; @@ -79,7 +76,6 @@ fn unwrapSimpleValueFromErrorDo() anyerror!isize { } test "error return in assignment" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; doErrReturnInAssignment() catch unreachable; @@ -126,7 +122,6 @@ test "debug info for optional error set" { } test "implicit cast to optional to error union to return result loc" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const S = struct { @@ -149,7 +144,6 @@ test "implicit cast to optional to error union to return result loc" { test "fn returning empty error set can be passed as fn returning any error" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO entry(); @@ -159,7 +153,6 @@ test "fn returning empty error set can be passed as fn returning any error" { test "fn returning empty error set can be passed as fn returning any error - pointer" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO entryPtr(); @@ -249,7 +242,6 @@ fn testExplicitErrorSetCast(set1: Set1) !void { test "comptime test error for empty error set" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try testComptimeTestErrorEmptySet(1234); @@ -268,7 +260,6 @@ fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) !void { test "comptime err to int of error set with only 1 possible value" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A)); @@ -323,7 +314,6 @@ fn quux_1() !i32 { } test "error: Zero sized error set returned with value payload crash" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; _ = try foo3(0); @@ -422,7 +412,6 @@ test "nested error union function call in optional unwrap" { test "return function call to error set from error union function" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { @@ -455,7 +444,6 @@ test "optional error set is the same size as error set" { test "nested catch" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { @@ -487,7 +475,6 @@ test "function pointer with return type that is error union with payload which i if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 0ea3a33990..dde27afe3f 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -90,7 +90,6 @@ fn letsTryToCompareBools(a: bool, b: bool) bool { return max(bool, a, b); } test "inlined block and runtime block phi" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try expect(letsTryToCompareBools(true, true)); @@ -390,7 +389,6 @@ test "return 0 from function that has u0 return type" { } test "statically initialized struct" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO st_init_str_foo.x += 1; @@ -502,7 +500,6 @@ test "comptime shlWithOverflow" { } test "const ptr to variable data changes at runtime" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try expect(foo_ref.name[0] == 'a'); @@ -605,8 +602,6 @@ fn testCompTimeUIntComparisons(x: u32) void { const hi1 = "hi"; const hi2 = hi1; test "const global shares pointer with other same one" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - try assertEqualPtrs(&hi1[0], &hi2[0]); comptime try expect(&hi1[0] == &hi2[0]); } @@ -976,7 +971,6 @@ test "closure capture type of runtime-known parameter" { test "comptime break passing through runtime condition converted to runtime break" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -1061,7 +1055,6 @@ test "comptime break operand passing through runtime condition converted to runt test "comptime break operand passing through runtime switch converted to runtime break" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest(runtime: u8) !void { @@ -1227,7 +1220,6 @@ test "storing an array of type in a field" { test "pass pointer to field of comptime-only type as a runtime parameter" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { const Mixed = struct { diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index 324a2ad247..383d553781 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -197,7 +197,6 @@ fn addPointCoords(pt: Point) i32 { } test "pass by non-copying value through var arg" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try expect((try addPointCoordsVar(Point{ .x = 1, .y = 2 })) == 3); diff --git a/test/behavior/if.zig b/test/behavior/if.zig index 2f5a52f7e2..d59a974ce4 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -44,7 +44,6 @@ var global_with_val: anyerror!u32 = 0; var global_with_err: anyerror!u32 = error.SomeError; test "unwrap mutable global var" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (global_with_val) |v| { diff --git a/test/behavior/math.zig b/test/behavior/math.zig index 3b73d93c01..2b10996bfb 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -652,7 +652,6 @@ test "@addWithOverflow" { test "small int addition" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var x: u2 = 0; try expect(x == 0); @@ -1136,8 +1135,6 @@ fn testShrExact(x: u8) !void { } test "shift left/right on u0 operand" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - const S = struct { fn doTheTest() !void { var x: u0 = 0; diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index a47d931883..adbc308742 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -84,7 +84,6 @@ test "assigning integer to C pointer" { test "C pointer comparison and arithmetic" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest() !void { @@ -430,7 +429,6 @@ test "indexing array with sentinel returns correct type" { test "element pointer to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -452,7 +450,6 @@ test "element pointer to slice" { test "element pointer arithmetic to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn doTheTest() !void { @@ -476,8 +473,6 @@ test "element pointer arithmetic to slice" { } test "array slicing to slice" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - const S = struct { fn doTheTest() !void { var str: [5]i32 = [_]i32{ 1, 2, 3, 4, 5 }; diff --git a/test/behavior/reflection.zig b/test/behavior/reflection.zig index 865813a663..899628a938 100644 --- a/test/behavior/reflection.zig +++ b/test/behavior/reflection.zig @@ -27,7 +27,6 @@ fn dummy(a: bool, b: i32, c: f32) i32 { test "reflection: @field" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO var f = Foo{ diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index e2694759bb..5e0498342c 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -118,7 +118,6 @@ test "slice of type" { test "generic malloc free" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const a = memAlloc(u8, 10) catch unreachable; @@ -482,7 +481,6 @@ test "slice pointer-to-array null terminated" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO comptime { var array = [5:0]u8{ 1, 2, 3, 4, 5 }; @@ -508,7 +506,6 @@ test "slice pointer-to-array null terminated" { test "slice pointer-to-array zero length" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO comptime { { @@ -643,7 +640,6 @@ test "slicing array with sentinel as end index" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn do() !void { @@ -664,7 +660,6 @@ test "slicing slice with sentinel as end index" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn do() !void { diff --git a/test/behavior/struct_contains_slice_of_itself.zig b/test/behavior/struct_contains_slice_of_itself.zig index cbff2514ea..feb382ed3e 100644 --- a/test/behavior/struct_contains_slice_of_itself.zig +++ b/test/behavior/struct_contains_slice_of_itself.zig @@ -13,7 +13,6 @@ const NodeAligned = struct { test "struct contains slice of itself" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO var other_nodes = [_]Node{ @@ -54,7 +53,6 @@ test "struct contains slice of itself" { test "struct contains aligned slice of itself" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO var other_nodes = [_]NodeAligned{ diff --git a/test/behavior/tuple.zig b/test/behavior/tuple.zig index f9237bb230..13772865ef 100644 --- a/test/behavior/tuple.zig +++ b/test/behavior/tuple.zig @@ -124,7 +124,6 @@ test "tuple initializer for var" { test "array-like initializer for tuple types" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const T = @Type(.{ .Struct = .{ diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index 7bbfbbc1ab..b1012e69c8 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -527,7 +527,6 @@ test "type info for async frames" { test "Declarations are returned in declaration order" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const S = struct { @@ -552,7 +551,6 @@ test "Struct.is_tuple for anon list literal" { test "Struct.is_tuple for anon struct literal" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const info = @typeInfo(@TypeOf(.{ .a = 0 })); try expect(!info.Struct.is_tuple); diff --git a/test/behavior/union.zig b/test/behavior/union.zig index caa5d26aea..3c8874e3a8 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -36,7 +36,6 @@ test "init union with runtime value - floats" { } test "basic unions" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var foo = Foo{ .int = 1 }; @@ -91,7 +90,6 @@ const FooExtern = extern union { }; test "basic extern unions" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var foo = FooExtern{ .int = 1 }; @@ -398,7 +396,6 @@ test "tagged union with no payloads" { } test "union with only 1 field casted to its enum type" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Literal = union(enum) { @@ -487,7 +484,6 @@ test "union initializer generates padding only if needed" { } test "runtime tag name with single field" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const U = union(enum) { @@ -540,7 +536,6 @@ const Baz = enum { A, B, C, D }; test "tagged union type" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const foo1 = TaggedFoo{ .One = 13 }; @@ -670,7 +665,6 @@ const PartialInstWithPayload = union(enum) { }; test "union with only 1 field casted to its enum type which has enum value specified" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const Literal = union(enum) { @@ -1110,7 +1104,6 @@ test "union enum type gets a separate scope" { test "global variable struct contains union initialized to non-most-aligned field" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const T = struct { const U = union(enum) { diff --git a/test/behavior/var_args.zig b/test/behavior/var_args.zig index d1baf7bd31..c482498a71 100644 --- a/test/behavior/var_args.zig +++ b/test/behavior/var_args.zig @@ -39,7 +39,6 @@ fn addSomeStuff(args: anytype) i32 { } test "runtime parameter before var args" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try expect((try extraFn(10, .{})) == 0); diff --git a/test/behavior/while.zig b/test/behavior/while.zig index 71f1d253e9..b664e73b89 100644 --- a/test/behavior/while.zig +++ b/test/behavior/while.zig @@ -256,7 +256,6 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { } test "while on error union with else result follow else prong" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const result = while (returnError()) |value| { @@ -266,7 +265,6 @@ test "while on error union with else result follow else prong" { } test "while on error union with else result follow break prong" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const result = while (returnSuccess(10)) |value| { diff --git a/test/behavior/widening.zig b/test/behavior/widening.zig index a6475e88e6..691755ac2a 100644 --- a/test/behavior/widening.zig +++ b/test/behavior/widening.zig @@ -30,7 +30,6 @@ test "integer widening u0 to u8" { test "implicit unsigned integer to signed integer" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO var a: u8 = 250; -- cgit v1.2.3