aboutsummaryrefslogtreecommitdiff
path: root/test/behavior
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-01-26 19:59:39 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-01-26 20:02:01 -0700
commit82bd0ac572f14d1e3a13737f4daf00a1ee8041a2 (patch)
tree38efbcea86e28b16a65d36c8866f4870085f9e44 /test/behavior
parentdb55f469c12c01831bd393c6701c26c15ffe726c (diff)
downloadzig-82bd0ac572f14d1e3a13737f4daf00a1ee8041a2.tar.gz
zig-82bd0ac572f14d1e3a13737f4daf00a1ee8041a2.zip
Sema: implement struct init is_ref=true
Takes advantage of the pattern already established with array_init_anon. Also upgrades array_init (non-anon) to the pattern. Implements comptime struct value equality and pointer value hashing.
Diffstat (limited to 'test/behavior')
-rw-r--r--test/behavior/enum.zig113
-rw-r--r--test/behavior/enum_llvm.zig105
-rw-r--r--test/behavior/pointers.zig282
-rw-r--r--test/behavior/pointers_stage1.zig256
-rw-r--r--test/behavior/ptrcast.zig77
-rw-r--r--test/behavior/ptrcast_stage1.zig73
6 files changed, 472 insertions, 434 deletions
diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig
index 0a0d7e5a15..119a999366 100644
--- a/test/behavior/enum.zig
+++ b/test/behavior/enum.zig
@@ -972,3 +972,116 @@ fn test3_2(f: Test3Foo) !void {
else => unreachable,
}
}
+
+test "@tagName" {
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+
+ try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
+ comptime try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
+}
+
+fn testEnumTagNameBare(n: anytype) []const u8 {
+ return @tagName(n);
+}
+
+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
+
+ try expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B"));
+ comptime try expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B"));
+}
+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
+
+ const S = struct {
+ fn doTheTest(n: BareNumber) !void {
+ try expect(@tagName(n)[3] == 0);
+ }
+ };
+ try S.doTheTest(.Two);
+ try comptime S.doTheTest(.Two);
+}
+
+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
+
+ const LocalFoo = enum(u8) {
+ A = 1,
+ B = 0,
+ };
+ var b = LocalFoo.B;
+ try expect(mem.eql(u8, @tagName(b), "B"));
+}
+
+test "@tagName on enum literals" {
+ try expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));
+ comptime try expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));
+}
+
+test "enum literal casting to optional" {
+ var bar: ?Bar = undefined;
+ bar = .B;
+
+ try expect(bar.? == Bar.B);
+}
+
+const A = enum(u3) { One, Two, Three, Four, One2, Two2, Three2, Four2 };
+const B = enum(u3) { One3, Two3, Three3, Four3, One23, Two23, Three23, Four23 };
+const C = enum(u2) { One4, Two4, Three4, Four4 };
+
+const BitFieldOfEnums = packed struct {
+ a: A,
+ b: B,
+ c: C,
+};
+
+const bit_field_1 = BitFieldOfEnums{
+ .a = A.Two,
+ .b = B.Three3,
+ .c = C.Four4,
+};
+
+test "bit field access with enum fields" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+
+ var data = bit_field_1;
+ try expect(getA(&data) == A.Two);
+ try expect(getB(&data) == B.Three3);
+ try expect(getC(&data) == C.Four4);
+ comptime try expect(@sizeOf(BitFieldOfEnums) == 1);
+
+ data.b = B.Four3;
+ try expect(data.b == B.Four3);
+
+ data.a = A.Three;
+ try expect(data.a == A.Three);
+ try expect(data.b == B.Four3);
+}
+
+fn getA(data: *const BitFieldOfEnums) A {
+ return data.a;
+}
+
+fn getB(data: *const BitFieldOfEnums) B {
+ return data.b;
+}
+
+fn getC(data: *const BitFieldOfEnums) C {
+ return data.c;
+}
+
+test "enum literal in array literal" {
+ const Items = enum { one, two };
+ const array = [_]Items{ .one, .two };
+
+ try expect(array[0] == .one);
+ try expect(array[1] == .two);
+}
diff --git a/test/behavior/enum_llvm.zig b/test/behavior/enum_llvm.zig
deleted file mode 100644
index 81a1c72e59..0000000000
--- a/test/behavior/enum_llvm.zig
+++ /dev/null
@@ -1,105 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-const mem = std.mem;
-const Tag = std.meta.Tag;
-
-test "@tagName" {
- try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
- comptime try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
-}
-
-fn testEnumTagNameBare(n: anytype) []const u8 {
- return @tagName(n);
-}
-
-const BareNumber = enum { One, Two, Three };
-
-test "@tagName non-exhaustive enum" {
- try expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B"));
- comptime try expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B"));
-}
-const NonExhaustive = enum(u8) { A, B, _ };
-
-test "@tagName is null-terminated" {
- const S = struct {
- fn doTheTest(n: BareNumber) !void {
- try expect(@tagName(n)[3] == 0);
- }
- };
- try S.doTheTest(.Two);
- try comptime S.doTheTest(.Two);
-}
-
-test "tag name with assigned enum values" {
- const LocalFoo = enum(u8) {
- A = 1,
- B = 0,
- };
- var b = LocalFoo.B;
- try expect(mem.eql(u8, @tagName(b), "B"));
-}
-
-test "@tagName on enum literals" {
- try expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));
- comptime try expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));
-}
-
-const Bar = enum { A, B, C, D };
-
-test "enum literal casting to optional" {
- var bar: ?Bar = undefined;
- bar = .B;
-
- try expect(bar.? == Bar.B);
-}
-
-const A = enum(u3) { One, Two, Three, Four, One2, Two2, Three2, Four2 };
-const B = enum(u3) { One3, Two3, Three3, Four3, One23, Two23, Three23, Four23 };
-const C = enum(u2) { One4, Two4, Three4, Four4 };
-
-const BitFieldOfEnums = packed struct {
- a: A,
- b: B,
- c: C,
-};
-
-const bit_field_1 = BitFieldOfEnums{
- .a = A.Two,
- .b = B.Three3,
- .c = C.Four4,
-};
-
-test "bit field access with enum fields" {
- var data = bit_field_1;
- try expect(getA(&data) == A.Two);
- try expect(getB(&data) == B.Three3);
- try expect(getC(&data) == C.Four4);
- comptime try expect(@sizeOf(BitFieldOfEnums) == 1);
-
- data.b = B.Four3;
- try expect(data.b == B.Four3);
-
- data.a = A.Three;
- try expect(data.a == A.Three);
- try expect(data.b == B.Four3);
-}
-
-fn getA(data: *const BitFieldOfEnums) A {
- return data.a;
-}
-
-fn getB(data: *const BitFieldOfEnums) B {
- return data.b;
-}
-
-fn getC(data: *const BitFieldOfEnums) C {
- return data.c;
-}
-
-test "enum literal in array literal" {
- const Items = enum { one, two };
- const array = [_]Items{ .one, .two };
-
- try expect(array[0] == .one);
- try expect(array[1] == .two);
-}
diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig
index 32b88a2522..a642da858b 100644
--- a/test/behavior/pointers.zig
+++ b/test/behavior/pointers.zig
@@ -1,3 +1,4 @@
+const builtin = @import("builtin");
const std = @import("std");
const testing = std.testing;
const expect = testing.expect;
@@ -97,3 +98,284 @@ test "C pointer comparison and arithmetic" {
try S.doTheTest();
comptime try S.doTheTest();
}
+
+test "dereference pointer again" {
+ try testDerefPtrOneVal();
+ comptime try testDerefPtrOneVal();
+}
+
+const Foo1 = struct {
+ x: void,
+};
+
+fn testDerefPtrOneVal() !void {
+ // Foo1 satisfies the OnePossibleValueYes criteria
+ const x = &Foo1{ .x = {} };
+ const y = x.*;
+ try expect(@TypeOf(y.x) == void);
+}
+
+test "peer type resolution with C pointers" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ var ptr_one: *u8 = undefined;
+ var ptr_many: [*]u8 = undefined;
+ var ptr_c: [*c]u8 = undefined;
+ var t = true;
+ var x1 = if (t) ptr_one else ptr_c;
+ var x2 = if (t) ptr_many else ptr_c;
+ var x3 = if (t) ptr_c else ptr_one;
+ var x4 = if (t) ptr_c else ptr_many;
+ try expect(@TypeOf(x1) == [*c]u8);
+ try expect(@TypeOf(x2) == [*c]u8);
+ try expect(@TypeOf(x3) == [*c]u8);
+ try expect(@TypeOf(x4) == [*c]u8);
+}
+
+test "implicit casting between C pointer and optional non-C pointer" {
+ var slice: []const u8 = "aoeu";
+ const opt_many_ptr: ?[*]const u8 = slice.ptr;
+ var ptr_opt_many_ptr = &opt_many_ptr;
+ var c_ptr: [*c]const [*c]const u8 = ptr_opt_many_ptr;
+ try expect(c_ptr.*.* == 'a');
+ ptr_opt_many_ptr = c_ptr;
+ try expect(ptr_opt_many_ptr.*.?[1] == 'o');
+}
+
+test "implicit cast error unions with non-optional to optional pointer" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ try expectError(error.Fail, foo());
+ }
+ fn foo() anyerror!?*u8 {
+ return bar() orelse error.Fail;
+ }
+ fn bar() ?*u8 {
+ return null;
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "compare equality of optional and non-optional pointer" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const a = @intToPtr(*const usize, 0x12345678);
+ const b = @intToPtr(?*usize, 0x12345678);
+ try expect(a == b);
+ try expect(b == a);
+}
+
+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
+
+ var ptr = @intToPtr([*]allowzero i32, 0);
+ var opt_ptr: ?[*]allowzero i32 = ptr;
+ try expect(opt_ptr != null);
+ try expect(@ptrToInt(ptr) == 0);
+ var runtime_zero: usize = 0;
+ var slice = ptr[runtime_zero..10];
+ comptime try expect(@TypeOf(slice) == []allowzero i32);
+ try expect(@ptrToInt(&slice[5]) == 20);
+
+ comptime try expect(@typeInfo(@TypeOf(ptr)).Pointer.is_allowzero);
+ comptime try expect(@typeInfo(@TypeOf(slice)).Pointer.is_allowzero);
+}
+
+test "assign null directly to C pointer and test null equality" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ var x: [*c]i32 = null;
+ try expect(x == null);
+ try expect(null == x);
+ try expect(!(x != null));
+ try expect(!(null != x));
+ if (x) |same_x| {
+ _ = same_x;
+ @panic("fail");
+ }
+ var otherx: i32 = undefined;
+ try expect((x orelse &otherx) == &otherx);
+
+ const y: [*c]i32 = null;
+ comptime try expect(y == null);
+ comptime try expect(null == y);
+ comptime try expect(!(y != null));
+ comptime try expect(!(null != y));
+ if (y) |same_y| {
+ _ = same_y;
+ @panic("fail");
+ }
+ const othery: i32 = undefined;
+ comptime try expect((y orelse &othery) == &othery);
+
+ var n: i32 = 1234;
+ var x1: [*c]i32 = &n;
+ try expect(!(x1 == null));
+ try expect(!(null == x1));
+ try expect(x1 != null);
+ try expect(null != x1);
+ try expect(x1.?.* == 1234);
+ if (x1) |same_x1| {
+ try expect(same_x1.* == 1234);
+ } else {
+ @panic("fail");
+ }
+ try expect((x1 orelse &otherx) == x1);
+
+ const nc: i32 = 1234;
+ const y1: [*c]const i32 = &nc;
+ comptime try expect(!(y1 == null));
+ comptime try expect(!(null == y1));
+ comptime try expect(y1 != null);
+ comptime try expect(null != y1);
+ comptime try expect(y1.?.* == 1234);
+ if (y1) |same_y1| {
+ try expect(same_y1.* == 1234);
+ } else {
+ @compileError("fail");
+ }
+ comptime try expect((y1 orelse &othery) == y1);
+}
+
+test "null terminated pointer" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var array_with_zero = [_:0]u8{ 'h', 'e', 'l', 'l', 'o' };
+ var zero_ptr: [*:0]const u8 = @ptrCast([*:0]const u8, &array_with_zero);
+ var no_zero_ptr: [*]const u8 = zero_ptr;
+ var zero_ptr_again = @ptrCast([*:0]const u8, no_zero_ptr);
+ try expect(std.mem.eql(u8, std.mem.sliceTo(zero_ptr_again, 0), "hello"));
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "allow any sentinel" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var array = [_:std.math.minInt(i32)]i32{ 1, 2, 3, 4 };
+ var ptr: [*:std.math.minInt(i32)]i32 = &array;
+ try expect(ptr[4] == std.math.minInt(i32));
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "pointer sentinel with enums" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const Number = enum {
+ one,
+ two,
+ sentinel,
+ };
+
+ fn doTheTest() !void {
+ var ptr: [*:.sentinel]const Number = &[_:.sentinel]Number{ .one, .two, .two, .one };
+ try expect(ptr[4] == .sentinel); // TODO this should be comptime try expect, see #3731
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "pointer sentinel with optional element" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var ptr: [*:null]const ?i32 = &[_:null]?i32{ 1, 2, 3, 4 };
+ try expect(ptr[4] == null); // TODO this should be comptime try expect, see #3731
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "pointer sentinel with +inf" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ const inf = std.math.inf_f32;
+ var ptr: [*:inf]const f32 = &[_:inf]f32{ 1.1, 2.2, 3.3, 4.4 };
+ try expect(ptr[4] == inf); // TODO this should be comptime try expect, see #3731
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "pointer to array at fixed address" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const array = @intToPtr(*volatile [1]u32, 0x10);
+ // Silly check just to reference `array`
+ try expect(@ptrToInt(&array[0]) == 0x10);
+}
+
+test "pointer arithmetic affects the alignment" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ {
+ var ptr: [*]align(8) u32 = undefined;
+ var x: usize = 1;
+
+ try expect(@typeInfo(@TypeOf(ptr)).Pointer.alignment == 8);
+ const ptr1 = ptr + 1; // 1 * 4 = 4 -> lcd(4,8) = 4
+ try expect(@typeInfo(@TypeOf(ptr1)).Pointer.alignment == 4);
+ const ptr2 = ptr + 4; // 4 * 4 = 16 -> lcd(16,8) = 8
+ try expect(@typeInfo(@TypeOf(ptr2)).Pointer.alignment == 8);
+ const ptr3 = ptr + 0; // no-op
+ try expect(@typeInfo(@TypeOf(ptr3)).Pointer.alignment == 8);
+ const ptr4 = ptr + x; // runtime-known addend
+ try expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 4);
+ }
+ {
+ var ptr: [*]align(8) [3]u8 = undefined;
+ var x: usize = 1;
+
+ const ptr1 = ptr + 17; // 3 * 17 = 51
+ try expect(@typeInfo(@TypeOf(ptr1)).Pointer.alignment == 1);
+ const ptr2 = ptr + x; // runtime-known addend
+ try expect(@typeInfo(@TypeOf(ptr2)).Pointer.alignment == 1);
+ const ptr3 = ptr + 8; // 3 * 8 = 24 -> lcd(8,24) = 8
+ try expect(@typeInfo(@TypeOf(ptr3)).Pointer.alignment == 8);
+ const ptr4 = ptr + 4; // 3 * 4 = 12 -> lcd(8,12) = 4
+ try expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 4);
+ }
+}
+
+test "@ptrToInt on null optional at comptime" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ {
+ const pointer = @intToPtr(?*u8, 0x000);
+ const x = @ptrToInt(pointer);
+ _ = x;
+ comptime try expect(0 == @ptrToInt(pointer));
+ }
+ {
+ const pointer = @intToPtr(?*u8, 0xf00);
+ comptime try expect(0xf00 == @ptrToInt(pointer));
+ }
+}
+
+test "indexing array with sentinel returns correct type" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ var s: [:0]const u8 = "abc";
+ try testing.expectEqualSlices(u8, "*const u8", @typeName(@TypeOf(&s[0])));
+}
diff --git a/test/behavior/pointers_stage1.zig b/test/behavior/pointers_stage1.zig
deleted file mode 100644
index 9d550db55b..0000000000
--- a/test/behavior/pointers_stage1.zig
+++ /dev/null
@@ -1,256 +0,0 @@
-const std = @import("std");
-const testing = std.testing;
-const expect = testing.expect;
-const expectError = testing.expectError;
-
-const Foo1 = struct {
- x: void,
-};
-
-test "dereference pointer again" {
- try testDerefPtrOneVal();
- comptime try testDerefPtrOneVal();
-}
-
-fn testDerefPtrOneVal() !void {
- // Foo1 satisfies the OnePossibleValueYes criteria
- const x = &Foo1{ .x = {} };
- const y = x.*;
- try expect(@TypeOf(y.x) == void);
-}
-
-test "peer type resolution with C pointers" {
- var ptr_one: *u8 = undefined;
- var ptr_many: [*]u8 = undefined;
- var ptr_c: [*c]u8 = undefined;
- var t = true;
- var x1 = if (t) ptr_one else ptr_c;
- var x2 = if (t) ptr_many else ptr_c;
- var x3 = if (t) ptr_c else ptr_one;
- var x4 = if (t) ptr_c else ptr_many;
- try expect(@TypeOf(x1) == [*c]u8);
- try expect(@TypeOf(x2) == [*c]u8);
- try expect(@TypeOf(x3) == [*c]u8);
- try expect(@TypeOf(x4) == [*c]u8);
-}
-
-test "implicit casting between C pointer and optional non-C pointer" {
- var slice: []const u8 = "aoeu";
- const opt_many_ptr: ?[*]const u8 = slice.ptr;
- var ptr_opt_many_ptr = &opt_many_ptr;
- var c_ptr: [*c]const [*c]const u8 = ptr_opt_many_ptr;
- try expect(c_ptr.*.* == 'a');
- ptr_opt_many_ptr = c_ptr;
- try expect(ptr_opt_many_ptr.*.?[1] == 'o');
-}
-
-test "implicit cast error unions with non-optional to optional pointer" {
- const S = struct {
- fn doTheTest() !void {
- try expectError(error.Fail, foo());
- }
- fn foo() anyerror!?*u8 {
- return bar() orelse error.Fail;
- }
- fn bar() ?*u8 {
- return null;
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "compare equality of optional and non-optional pointer" {
- const a = @intToPtr(*const usize, 0x12345678);
- const b = @intToPtr(?*usize, 0x12345678);
- try expect(a == b);
- try expect(b == a);
-}
-
-test "allowzero pointer and slice" {
- var ptr = @intToPtr([*]allowzero i32, 0);
- var opt_ptr: ?[*]allowzero i32 = ptr;
- try expect(opt_ptr != null);
- try expect(@ptrToInt(ptr) == 0);
- var runtime_zero: usize = 0;
- var slice = ptr[runtime_zero..10];
- comptime try expect(@TypeOf(slice) == []allowzero i32);
- try expect(@ptrToInt(&slice[5]) == 20);
-
- comptime try expect(@typeInfo(@TypeOf(ptr)).Pointer.is_allowzero);
- comptime try expect(@typeInfo(@TypeOf(slice)).Pointer.is_allowzero);
-}
-
-test "assign null directly to C pointer and test null equality" {
- var x: [*c]i32 = null;
- try expect(x == null);
- try expect(null == x);
- try expect(!(x != null));
- try expect(!(null != x));
- if (x) |same_x| {
- _ = same_x;
- @panic("fail");
- }
- var otherx: i32 = undefined;
- try expect((x orelse &otherx) == &otherx);
-
- const y: [*c]i32 = null;
- comptime try expect(y == null);
- comptime try expect(null == y);
- comptime try expect(!(y != null));
- comptime try expect(!(null != y));
- if (y) |same_y| {
- _ = same_y;
- @panic("fail");
- }
- const othery: i32 = undefined;
- comptime try expect((y orelse &othery) == &othery);
-
- var n: i32 = 1234;
- var x1: [*c]i32 = &n;
- try expect(!(x1 == null));
- try expect(!(null == x1));
- try expect(x1 != null);
- try expect(null != x1);
- try expect(x1.?.* == 1234);
- if (x1) |same_x1| {
- try expect(same_x1.* == 1234);
- } else {
- @panic("fail");
- }
- try expect((x1 orelse &otherx) == x1);
-
- const nc: i32 = 1234;
- const y1: [*c]const i32 = &nc;
- comptime try expect(!(y1 == null));
- comptime try expect(!(null == y1));
- comptime try expect(y1 != null);
- comptime try expect(null != y1);
- comptime try expect(y1.?.* == 1234);
- if (y1) |same_y1| {
- try expect(same_y1.* == 1234);
- } else {
- @compileError("fail");
- }
- comptime try expect((y1 orelse &othery) == y1);
-}
-
-test "null terminated pointer" {
- const S = struct {
- fn doTheTest() !void {
- var array_with_zero = [_:0]u8{ 'h', 'e', 'l', 'l', 'o' };
- var zero_ptr: [*:0]const u8 = @ptrCast([*:0]const u8, &array_with_zero);
- var no_zero_ptr: [*]const u8 = zero_ptr;
- var zero_ptr_again = @ptrCast([*:0]const u8, no_zero_ptr);
- try expect(std.mem.eql(u8, std.mem.sliceTo(zero_ptr_again, 0), "hello"));
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "allow any sentinel" {
- const S = struct {
- fn doTheTest() !void {
- var array = [_:std.math.minInt(i32)]i32{ 1, 2, 3, 4 };
- var ptr: [*:std.math.minInt(i32)]i32 = &array;
- try expect(ptr[4] == std.math.minInt(i32));
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "pointer sentinel with enums" {
- const S = struct {
- const Number = enum {
- one,
- two,
- sentinel,
- };
-
- fn doTheTest() !void {
- var ptr: [*:.sentinel]const Number = &[_:.sentinel]Number{ .one, .two, .two, .one };
- try expect(ptr[4] == .sentinel); // TODO this should be comptime try expect, see #3731
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "pointer sentinel with optional element" {
- const S = struct {
- fn doTheTest() !void {
- var ptr: [*:null]const ?i32 = &[_:null]?i32{ 1, 2, 3, 4 };
- try expect(ptr[4] == null); // TODO this should be comptime try expect, see #3731
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "pointer sentinel with +inf" {
- const S = struct {
- fn doTheTest() !void {
- const inf = std.math.inf_f32;
- var ptr: [*:inf]const f32 = &[_:inf]f32{ 1.1, 2.2, 3.3, 4.4 };
- try expect(ptr[4] == inf); // TODO this should be comptime try expect, see #3731
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "pointer to array at fixed address" {
- const array = @intToPtr(*volatile [1]u32, 0x10);
- // Silly check just to reference `array`
- try expect(@ptrToInt(&array[0]) == 0x10);
-}
-
-test "pointer arithmetic affects the alignment" {
- {
- var ptr: [*]align(8) u32 = undefined;
- var x: usize = 1;
-
- try expect(@typeInfo(@TypeOf(ptr)).Pointer.alignment == 8);
- const ptr1 = ptr + 1; // 1 * 4 = 4 -> lcd(4,8) = 4
- try expect(@typeInfo(@TypeOf(ptr1)).Pointer.alignment == 4);
- const ptr2 = ptr + 4; // 4 * 4 = 16 -> lcd(16,8) = 8
- try expect(@typeInfo(@TypeOf(ptr2)).Pointer.alignment == 8);
- const ptr3 = ptr + 0; // no-op
- try expect(@typeInfo(@TypeOf(ptr3)).Pointer.alignment == 8);
- const ptr4 = ptr + x; // runtime-known addend
- try expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 4);
- }
- {
- var ptr: [*]align(8) [3]u8 = undefined;
- var x: usize = 1;
-
- const ptr1 = ptr + 17; // 3 * 17 = 51
- try expect(@typeInfo(@TypeOf(ptr1)).Pointer.alignment == 1);
- const ptr2 = ptr + x; // runtime-known addend
- try expect(@typeInfo(@TypeOf(ptr2)).Pointer.alignment == 1);
- const ptr3 = ptr + 8; // 3 * 8 = 24 -> lcd(8,24) = 8
- try expect(@typeInfo(@TypeOf(ptr3)).Pointer.alignment == 8);
- const ptr4 = ptr + 4; // 3 * 4 = 12 -> lcd(8,12) = 4
- try expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 4);
- }
-}
-
-test "@ptrToInt on null optional at comptime" {
- {
- const pointer = @intToPtr(?*u8, 0x000);
- const x = @ptrToInt(pointer);
- _ = x;
- comptime try expect(0 == @ptrToInt(pointer));
- }
- {
- const pointer = @intToPtr(?*u8, 0xf00);
- comptime try expect(0xf00 == @ptrToInt(pointer));
- }
-}
-
-test "indexing array with sentinel returns correct type" {
- var s: [:0]const u8 = "abc";
- try testing.expectEqualSlices(u8, "*const u8", @typeName(@TypeOf(&s[0])));
-}
diff --git a/test/behavior/ptrcast.zig b/test/behavior/ptrcast.zig
index 1a03964179..02ae0fd0c6 100644
--- a/test/behavior/ptrcast.zig
+++ b/test/behavior/ptrcast.zig
@@ -2,3 +2,80 @@ const std = @import("std");
const builtin = @import("builtin");
const expect = std.testing.expect;
const native_endian = builtin.target.cpu.arch.endian();
+
+test "reinterpret bytes as integer with nonzero offset" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testReinterpretBytesAsInteger();
+ comptime try testReinterpretBytesAsInteger();
+}
+
+fn testReinterpretBytesAsInteger() !void {
+ const bytes = "\x12\x34\x56\x78\xab";
+ const expected = switch (native_endian) {
+ .Little => 0xab785634,
+ .Big => 0x345678ab,
+ };
+ try expect(@ptrCast(*align(1) const u32, bytes[1..5]).* == expected);
+}
+
+test "reinterpret bytes of an array into an extern struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testReinterpretBytesAsExternStruct();
+ comptime try testReinterpretBytesAsExternStruct();
+}
+
+fn testReinterpretBytesAsExternStruct() !void {
+ var bytes align(2) = [_]u8{ 1, 2, 3, 4, 5, 6 };
+
+ const S = extern struct {
+ a: u8,
+ b: u16,
+ c: u8,
+ };
+
+ var ptr = @ptrCast(*const S, &bytes);
+ var val = ptr.c;
+ try expect(val == 5);
+}
+
+test "reinterpret struct field at comptime" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const numNative = comptime Bytes.init(0x12345678);
+ if (native_endian != .Little) {
+ try expect(std.mem.eql(u8, &[_]u8{ 0x12, 0x34, 0x56, 0x78 }, &numNative.bytes));
+ } else {
+ try expect(std.mem.eql(u8, &[_]u8{ 0x78, 0x56, 0x34, 0x12 }, &numNative.bytes));
+ }
+}
+
+const Bytes = struct {
+ bytes: [4]u8,
+
+ pub fn init(v: u32) Bytes {
+ var res: Bytes = undefined;
+ @ptrCast(*align(1) u32, &res.bytes).* = v;
+
+ return res;
+ }
+};
+
+test "comptime ptrcast keeps larger alignment" {
+ comptime {
+ const a: u32 = 1234;
+ const p = @ptrCast([*]const u8, &a);
+ try expect(@TypeOf(p) == [*]align(@alignOf(u32)) const u8);
+ }
+}
+
+test "implicit optional pointer to optional anyopaque pointer" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ var buf: [4]u8 = "aoeu".*;
+ var x: ?[*]u8 = &buf;
+ var y: ?*anyopaque = x;
+ var z = @ptrCast(*[4]u8, y);
+ try expect(std.mem.eql(u8, z, "aoeu"));
+}
diff --git a/test/behavior/ptrcast_stage1.zig b/test/behavior/ptrcast_stage1.zig
deleted file mode 100644
index 3bf6181a19..0000000000
--- a/test/behavior/ptrcast_stage1.zig
+++ /dev/null
@@ -1,73 +0,0 @@
-const std = @import("std");
-const builtin = @import("builtin");
-const expect = std.testing.expect;
-const native_endian = builtin.target.cpu.arch.endian();
-
-test "reinterpret bytes as integer with nonzero offset" {
- try testReinterpretBytesAsInteger();
- comptime try testReinterpretBytesAsInteger();
-}
-
-fn testReinterpretBytesAsInteger() !void {
- const bytes = "\x12\x34\x56\x78\xab";
- const expected = switch (native_endian) {
- .Little => 0xab785634,
- .Big => 0x345678ab,
- };
- try expect(@ptrCast(*align(1) const u32, bytes[1..5]).* == expected);
-}
-
-test "reinterpret bytes of an array into an extern struct" {
- try testReinterpretBytesAsExternStruct();
- comptime try testReinterpretBytesAsExternStruct();
-}
-
-fn testReinterpretBytesAsExternStruct() !void {
- var bytes align(2) = [_]u8{ 1, 2, 3, 4, 5, 6 };
-
- const S = extern struct {
- a: u8,
- b: u16,
- c: u8,
- };
-
- var ptr = @ptrCast(*const S, &bytes);
- var val = ptr.c;
- try expect(val == 5);
-}
-
-test "reinterpret struct field at comptime" {
- const numNative = comptime Bytes.init(0x12345678);
- if (native_endian != .Little) {
- try expect(std.mem.eql(u8, &[_]u8{ 0x12, 0x34, 0x56, 0x78 }, &numNative.bytes));
- } else {
- try expect(std.mem.eql(u8, &[_]u8{ 0x78, 0x56, 0x34, 0x12 }, &numNative.bytes));
- }
-}
-
-const Bytes = struct {
- bytes: [4]u8,
-
- pub fn init(v: u32) Bytes {
- var res: Bytes = undefined;
- @ptrCast(*align(1) u32, &res.bytes).* = v;
-
- return res;
- }
-};
-
-test "comptime ptrcast keeps larger alignment" {
- comptime {
- const a: u32 = 1234;
- const p = @ptrCast([*]const u8, &a);
- try expect(@TypeOf(p) == [*]align(@alignOf(u32)) const u8);
- }
-}
-
-test "implicit optional pointer to optional anyopaque pointer" {
- var buf: [4]u8 = "aoeu".*;
- var x: ?[*]u8 = &buf;
- var y: ?*anyopaque = x;
- var z = @ptrCast(*[4]u8, y);
- try expect(std.mem.eql(u8, z, "aoeu"));
-}