aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-10-07 00:46:05 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-10-07 00:46:05 -0700
commitb5a36f676b1fd69f195d9f1eb6e35f3eb2f15946 (patch)
tree92ce1ffa64bc2d32d5ef73dce66daf3c8e893ee6 /test
parentd6d05fc84d33c71434a1f8bae51ca5956e08cdf0 (diff)
parentf2d374e8465042fa5cb6bf2be7b9b086948f3a94 (diff)
downloadzig-b5a36f676b1fd69f195d9f1eb6e35f3eb2f15946.tar.gz
zig-b5a36f676b1fd69f195d9f1eb6e35f3eb2f15946.zip
Merge remote-tracking branch 'origin/master' into llvm11
Conflicts: cmake/Findllvm.cmake The llvm11 branch changed 10's to 11's and master branch added the "using LLVM_CONFIG_EXE" help message, so the resolution was to merge these changes together. I also added a check to make sure LLVM is built with AVR enabled, which is no longer an experimental target.
Diffstat (limited to 'test')
-rw-r--r--test/compile_errors.zig229
-rw-r--r--test/stage1/behavior/bugs/1467.zig7
-rw-r--r--test/stage1/behavior/type.zig43
-rw-r--r--test/stage1/behavior/type_info.zig21
-rw-r--r--test/stage1/behavior/vector.zig40
-rw-r--r--test/stage2/arm.zig116
-rw-r--r--test/stage2/test.zig154
-rw-r--r--test/translate_c.zig18
8 files changed, 512 insertions, 116 deletions
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 7a33de4f19..816d569b4d 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -2,20 +2,175 @@ const tests = @import("tests.zig");
const std = @import("std");
pub fn addCases(cases: *tests.CompileErrorContext) void {
- cases.add("slice sentinel mismatch",
+ cases.add("@Type for exhaustive enum with undefined tag type",
+ \\const TypeInfo = @import("builtin").TypeInfo;
+ \\const Tag = @Type(.{
+ \\ .Enum = .{
+ \\ .layout = .Auto,
+ \\ .tag_type = undefined,
+ \\ .fields = &[_]TypeInfo.EnumField{},
+ \\ .decls = &[_]TypeInfo.Declaration{},
+ \\ .is_exhaustive = false,
+ \\ },
+ \\});
\\export fn entry() void {
- \\ const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 };
+ \\ _ = @intToEnum(Tag, 0);
\\}
, &[_][]const u8{
- "tmp.zig:2:62: error: index 3 outside vector of size 3",
+ "tmp.zig:2:20: error: use of undefined value here causes undefined behavior",
});
- cases.add("slice sentinel mismatch",
+ cases.add("extern struct with non-extern-compatible integer tag type",
+ \\pub const E = enum(u31) { A, B, C };
+ \\pub const S = extern struct {
+ \\ e: E,
+ \\};
\\export fn entry() void {
- \\ const y: [:1]const u8 = &[_:2]u8{ 1, 2 };
+ \\ const s: S = undefined;
\\}
, &[_][]const u8{
- "tmp.zig:2:37: error: expected type '[:1]const u8', found '*const [2:2]u8'",
+ "tmp.zig:3:5: error: extern structs cannot contain fields of type 'E'",
+ });
+
+ cases.add("@Type for exhaustive enum with non-integer tag type",
+ \\const TypeInfo = @import("builtin").TypeInfo;
+ \\const Tag = @Type(.{
+ \\ .Enum = .{
+ \\ .layout = .Auto,
+ \\ .tag_type = bool,
+ \\ .fields = &[_]TypeInfo.EnumField{},
+ \\ .decls = &[_]TypeInfo.Declaration{},
+ \\ .is_exhaustive = false,
+ \\ },
+ \\});
+ \\export fn entry() void {
+ \\ _ = @intToEnum(Tag, 0);
+ \\}
+ , &[_][]const u8{
+ "tmp.zig:2:20: error: TypeInfo.Enum.tag_type must be an integer type, not 'bool'",
+ });
+
+ cases.add("extern struct with extern-compatible but inferred integer tag type",
+ \\pub const E = enum {
+ \\@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",
+ \\@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",
+ \\@"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34",
+ \\@"35",@"36",@"37",@"38",@"39",@"40",@"41",@"42",@"43",@"44",@"45",
+ \\@"46",@"47",@"48",@"49",@"50",@"51",@"52",@"53",@"54",@"55",@"56",
+ \\@"57",@"58",@"59",@"60",@"61",@"62",@"63",@"64",@"65",@"66",@"67",
+ \\@"68",@"69",@"70",@"71",@"72",@"73",@"74",@"75",@"76",@"77",@"78",
+ \\@"79",@"80",@"81",@"82",@"83",@"84",@"85",@"86",@"87",@"88",@"89",
+ \\@"90",@"91",@"92",@"93",@"94",@"95",@"96",@"97",@"98",@"99",@"100",
+ \\@"101",@"102",@"103",@"104",@"105",@"106",@"107",@"108",@"109",
+ \\@"110",@"111",@"112",@"113",@"114",@"115",@"116",@"117",@"118",
+ \\@"119",@"120",@"121",@"122",@"123",@"124",@"125",@"126",@"127",
+ \\@"128",@"129",@"130",@"131",@"132",@"133",@"134",@"135",@"136",
+ \\@"137",@"138",@"139",@"140",@"141",@"142",@"143",@"144",@"145",
+ \\@"146",@"147",@"148",@"149",@"150",@"151",@"152",@"153",@"154",
+ \\@"155",@"156",@"157",@"158",@"159",@"160",@"161",@"162",@"163",
+ \\@"164",@"165",@"166",@"167",@"168",@"169",@"170",@"171",@"172",
+ \\@"173",@"174",@"175",@"176",@"177",@"178",@"179",@"180",@"181",
+ \\@"182",@"183",@"184",@"185",@"186",@"187",@"188",@"189",@"190",
+ \\@"191",@"192",@"193",@"194",@"195",@"196",@"197",@"198",@"199",
+ \\@"200",@"201",@"202",@"203",@"204",@"205",@"206",@"207",@"208",
+ \\@"209",@"210",@"211",@"212",@"213",@"214",@"215",@"216",@"217",
+ \\@"218",@"219",@"220",@"221",@"222",@"223",@"224",@"225",@"226",
+ \\@"227",@"228",@"229",@"230",@"231",@"232",@"233",@"234",@"235",
+ \\@"236",@"237",@"238",@"239",@"240",@"241",@"242",@"243",@"244",
+ \\@"245",@"246",@"247",@"248",@"249",@"250",@"251",@"252",@"253",
+ \\@"254",@"255"
+ \\};
+ \\pub const S = extern struct {
+ \\ e: E,
+ \\};
+ \\export fn entry() void {
+ \\ if (@TagType(E) != u8) @compileError("did not infer u8 tag type");
+ \\ const s: S = undefined;
+ \\}
+ , &[_][]const u8{
+ "tmp.zig:31:5: error: extern structs cannot contain fields of type 'E'",
+ });
+
+ cases.add("@Type for tagged union with extra enum field",
+ \\const TypeInfo = @import("builtin").TypeInfo;
+ \\const Tag = @Type(.{
+ \\ .Enum = .{
+ \\ .layout = .Auto,
+ \\ .tag_type = u2,
+ \\ .fields = &[_]TypeInfo.EnumField{
+ \\ .{ .name = "signed", .value = 0 },
+ \\ .{ .name = "unsigned", .value = 1 },
+ \\ .{ .name = "arst", .value = 2 },
+ \\ },
+ \\ .decls = &[_]TypeInfo.Declaration{},
+ \\ .is_exhaustive = true,
+ \\ },
+ \\});
+ \\const Tagged = @Type(.{
+ \\ .Union = .{
+ \\ .layout = .Auto,
+ \\ .tag_type = Tag,
+ \\ .fields = &[_]TypeInfo.UnionField{
+ \\ .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
+ \\ .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
+ \\ },
+ \\ .decls = &[_]TypeInfo.Declaration{},
+ \\ },
+ \\});
+ \\export fn entry() void {
+ \\ var tagged = Tagged{ .signed = -1 };
+ \\ tagged = .{ .unsigned = 1 };
+ \\}
+ , &[_][]const u8{
+ "tmp.zig:15:23: error: enum field missing: 'arst'",
+ "tmp.zig:27:24: note: referenced here",
+ });
+ cases.add("@Type(.Fn) with is_generic = true",
+ \\const Foo = @Type(.{
+ \\ .Fn = .{
+ \\ .calling_convention = .Unspecified,
+ \\ .alignment = 0,
+ \\ .is_generic = true,
+ \\ .is_var_args = false,
+ \\ .return_type = u0,
+ \\ .args = &[_]@import("builtin").TypeInfo.FnArg{},
+ \\ },
+ \\});
+ \\comptime { _ = Foo; }
+ , &[_][]const u8{
+ "tmp.zig:1:20: error: TypeInfo.Fn.is_generic must be false for @Type",
+ });
+
+ cases.add("@Type(.Fn) with is_var_args = true and non-C callconv",
+ \\const Foo = @Type(.{
+ \\ .Fn = .{
+ \\ .calling_convention = .Unspecified,
+ \\ .alignment = 0,
+ \\ .is_generic = false,
+ \\ .is_var_args = true,
+ \\ .return_type = u0,
+ \\ .args = &[_]@import("builtin").TypeInfo.FnArg{},
+ \\ },
+ \\});
+ \\comptime { _ = Foo; }
+ , &[_][]const u8{
+ "tmp.zig:1:20: error: varargs functions must have C calling convention",
+ });
+
+ cases.add("@Type(.Fn) with return_type = null",
+ \\const Foo = @Type(.{
+ \\ .Fn = .{
+ \\ .calling_convention = .Unspecified,
+ \\ .alignment = 0,
+ \\ .is_generic = false,
+ \\ .is_var_args = false,
+ \\ .return_type = null,
+ \\ .args = &[_]@import("builtin").TypeInfo.FnArg{},
+ \\ },
+ \\});
+ \\comptime { _ = Foo; }
+ , &[_][]const u8{
+ "tmp.zig:1:20: error: TypeInfo.Fn.return_type must be non-null for @Type",
});
cases.add("@Type for union with opaque field",
@@ -25,7 +180,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ .layout = .Auto,
\\ .tag_type = null,
\\ .fields = &[_]TypeInfo.UnionField{
- \\ .{ .name = "foo", .field_type = @Type(.Opaque) },
+ \\ .{ .name = "foo", .field_type = @Type(.Opaque), .alignment = 1 },
\\ },
\\ .decls = &[_]TypeInfo.Declaration{},
\\ },
@@ -38,6 +193,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:13:17: note: referenced here",
});
+ cases.add("slice sentinel mismatch",
+ \\export fn entry() void {
+ \\ const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 };
+ \\}
+ , &[_][]const u8{
+ "tmp.zig:2:62: error: index 3 outside vector of size 3",
+ });
+
+ cases.add("slice sentinel mismatch",
+ \\export fn entry() void {
+ \\ const y: [:1]const u8 = &[_:2]u8{ 1, 2 };
+ \\}
+ , &[_][]const u8{
+ "tmp.zig:2:37: error: expected type '[:1]const u8', found '*const [2:2]u8'",
+ });
+
cases.add("@Type for union with zero fields",
\\const TypeInfo = @import("builtin").TypeInfo;
\\const Untagged = @Type(.{
@@ -94,9 +265,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ .layout = .Auto,
\\ .tag_type = Tag,
\\ .fields = &[_]TypeInfo.UnionField{
- \\ .{ .name = "signed", .field_type = i32 },
- \\ .{ .name = "unsigned", .field_type = u32 },
- \\ .{ .name = "arst", .field_type = f32 },
+ \\ .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
+ \\ .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
+ \\ .{ .name = "arst", .field_type = f32, .alignment = @alignOf(f32) },
\\ },
\\ .decls = &[_]TypeInfo.Declaration{},
\\ },
@@ -111,42 +282,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:27:24: note: referenced here",
});
- cases.add("@Type for tagged union with extra enum field",
- \\const TypeInfo = @import("builtin").TypeInfo;
- \\const Tag = @Type(.{
- \\ .Enum = .{
- \\ .layout = .Auto,
- \\ .tag_type = u2,
- \\ .fields = &[_]TypeInfo.EnumField{
- \\ .{ .name = "signed", .value = 0 },
- \\ .{ .name = "unsigned", .value = 1 },
- \\ .{ .name = "arst", .field_type = 2 },
- \\ },
- \\ .decls = &[_]TypeInfo.Declaration{},
- \\ .is_exhaustive = true,
- \\ },
- \\});
- \\const Tagged = @Type(.{
- \\ .Union = .{
- \\ .layout = .Auto,
- \\ .tag_type = Tag,
- \\ .fields = &[_]TypeInfo.UnionField{
- \\ .{ .name = "signed", .field_type = i32 },
- \\ .{ .name = "unsigned", .field_type = u32 },
- \\ },
- \\ .decls = &[_]TypeInfo.Declaration{},
- \\ },
- \\});
- \\export fn entry() void {
- \\ var tagged = Tagged{ .signed = -1 };
- \\ tagged = .{ .unsigned = 1 };
- \\}
- , &[_][]const u8{
- "tmp.zig:9:32: error: no member named 'field_type' in struct 'std.builtin.EnumField'",
- "tmp.zig:18:21: note: referenced here",
- "tmp.zig:27:18: note: referenced here",
- });
-
cases.add("@Type with undefined",
\\comptime {
\\ _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });
@@ -7556,7 +7691,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
});
cases.add( // fixed bug #2032
- "compile diagnostic string for top level decl type",
+ "compile diagnostic string for top level decl type",
\\export fn entry() void {
\\ var foo: u32 = @This(){};
\\}
diff --git a/test/stage1/behavior/bugs/1467.zig b/test/stage1/behavior/bugs/1467.zig
new file mode 100644
index 0000000000..71c55dc59c
--- /dev/null
+++ b/test/stage1/behavior/bugs/1467.zig
@@ -0,0 +1,7 @@
+pub const E = enum(u32) { A, B, C };
+pub const S = extern struct {
+ e: E,
+};
+test "bug 1467" {
+ const s: S = undefined;
+}
diff --git a/test/stage1/behavior/type.zig b/test/stage1/behavior/type.zig
index 38d23175d0..60a23ffa94 100644
--- a/test/stage1/behavior/type.zig
+++ b/test/stage1/behavior/type.zig
@@ -320,8 +320,8 @@ test "Type.Union" {
.layout = .Auto,
.tag_type = null,
.fields = &[_]TypeInfo.UnionField{
- .{ .name = "int", .field_type = i32 },
- .{ .name = "float", .field_type = f32 },
+ .{ .name = "int", .field_type = i32, .alignment = @alignOf(f32) },
+ .{ .name = "float", .field_type = f32, .alignment = @alignOf(f32) },
},
.decls = &[_]TypeInfo.Declaration{},
},
@@ -336,8 +336,8 @@ test "Type.Union" {
.layout = .Packed,
.tag_type = null,
.fields = &[_]TypeInfo.UnionField{
- .{ .name = "signed", .field_type = i32 },
- .{ .name = "unsigned", .field_type = u32 },
+ .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
+ .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
},
.decls = &[_]TypeInfo.Declaration{},
},
@@ -363,8 +363,8 @@ test "Type.Union" {
.layout = .Auto,
.tag_type = Tag,
.fields = &[_]TypeInfo.UnionField{
- .{ .name = "signed", .field_type = i32 },
- .{ .name = "unsigned", .field_type = u32 },
+ .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
+ .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
},
.decls = &[_]TypeInfo.Declaration{},
},
@@ -392,7 +392,7 @@ test "Type.Union from Type.Enum" {
.layout = .Auto,
.tag_type = Tag,
.fields = &[_]TypeInfo.UnionField{
- .{ .name = "working_as_expected", .field_type = u32 },
+ .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) },
},
.decls = &[_]TypeInfo.Declaration{},
},
@@ -408,7 +408,7 @@ test "Type.Union from regular enum" {
.layout = .Auto,
.tag_type = E,
.fields = &[_]TypeInfo.UnionField{
- .{ .name = "working_as_expected", .field_type = u32 },
+ .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) },
},
.decls = &[_]TypeInfo.Declaration{},
},
@@ -416,3 +416,30 @@ test "Type.Union from regular enum" {
_ = T;
_ = @typeInfo(T).Union;
}
+
+test "Type.Fn" {
+ // wasm doesn't support align attributes on functions
+ if (builtin.arch == .wasm32 or builtin.arch == .wasm64) return error.SkipZigTest;
+
+ const foo = struct {
+ fn func(a: usize, b: bool) align(4) callconv(.C) usize {
+ return 0;
+ }
+ }.func;
+ const Foo = @Type(@typeInfo(@TypeOf(foo)));
+ const foo_2: Foo = foo;
+}
+
+test "Type.BoundFn" {
+ // wasm doesn't support align attributes on functions
+ if (builtin.arch == .wasm32 or builtin.arch == .wasm64) return error.SkipZigTest;
+
+ const TestStruct = packed struct {
+ pub fn foo(self: *const @This()) align(4) callconv(.Unspecified) void {}
+ };
+ const test_instance: TestStruct = undefined;
+ testing.expect(std.meta.eql(
+ @typeName(@TypeOf(test_instance.foo)),
+ @typeName(@Type(@typeInfo(@TypeOf(test_instance.foo)))),
+ ));
+}
diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig
index 9e066d5f1a..8b413bf031 100644
--- a/test/stage1/behavior/type_info.zig
+++ b/test/stage1/behavior/type_info.zig
@@ -211,7 +211,9 @@ fn testUnion() void {
expect(notag_union_info.Union.tag_type == null);
expect(notag_union_info.Union.layout == .Auto);
expect(notag_union_info.Union.fields.len == 2);
+ expect(notag_union_info.Union.fields[0].alignment == @alignOf(void));
expect(notag_union_info.Union.fields[1].field_type == u32);
+ expect(notag_union_info.Union.fields[1].alignment == @alignOf(u32));
const TestExternUnion = extern union {
foo: *c_void,
@@ -229,13 +231,18 @@ test "type info: struct info" {
}
fn testStruct() void {
+ const unpacked_struct_info = @typeInfo(TestUnpackedStruct);
+ expect(unpacked_struct_info.Struct.fields[0].alignment == @alignOf(u32));
+
const struct_info = @typeInfo(TestStruct);
expect(struct_info == .Struct);
expect(struct_info.Struct.layout == .Packed);
expect(struct_info.Struct.fields.len == 4);
+ expect(struct_info.Struct.fields[0].alignment == 2 * @alignOf(usize));
expect(struct_info.Struct.fields[2].field_type == *TestStruct);
expect(struct_info.Struct.fields[2].default_value == null);
expect(struct_info.Struct.fields[3].default_value.? == 4);
+ expect(struct_info.Struct.fields[3].alignment == 1);
expect(struct_info.Struct.decls.len == 2);
expect(struct_info.Struct.decls[0].is_pub);
expect(!struct_info.Struct.decls[0].data.Fn.is_extern);
@@ -244,8 +251,12 @@ fn testStruct() void {
expect(struct_info.Struct.decls[0].data.Fn.fn_type == fn (*const TestStruct) void);
}
+const TestUnpackedStruct = struct {
+ fieldA: u32 = 4,
+};
+
const TestStruct = packed struct {
- fieldA: usize,
+ fieldA: usize align(2 * @alignOf(usize)),
fieldB: void,
fieldC: *Self,
fieldD: u32 = 4,
@@ -255,6 +266,8 @@ const TestStruct = packed struct {
};
test "type info: function type info" {
+ // wasm doesn't support align attributes on functions
+ if (builtin.arch == .wasm32 or builtin.arch == .wasm64) return error.SkipZigTest;
testFunction();
comptime testFunction();
}
@@ -262,11 +275,14 @@ test "type info: function type info" {
fn testFunction() void {
const fn_info = @typeInfo(@TypeOf(foo));
expect(fn_info == .Fn);
+ expect(fn_info.Fn.alignment == 0);
expect(fn_info.Fn.calling_convention == .C);
expect(!fn_info.Fn.is_generic);
expect(fn_info.Fn.args.len == 2);
expect(fn_info.Fn.is_var_args);
expect(fn_info.Fn.return_type.? == usize);
+ const fn_aligned_info = @typeInfo(@TypeOf(fooAligned));
+ expect(fn_aligned_info.Fn.alignment == 4);
const test_instance: TestStruct = undefined;
const bound_fn_info = @typeInfo(@TypeOf(test_instance.foo));
@@ -274,7 +290,8 @@ fn testFunction() void {
expect(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct);
}
-extern fn foo(a: usize, b: bool, ...) usize;
+extern fn foo(a: usize, b: bool, ...) callconv(.C) usize;
+extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize;
test "typeInfo with comptime parameter in struct fn def" {
const S = struct {
diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig
index dc9e49da43..aeb98f28fd 100644
--- a/test/stage1/behavior/vector.zig
+++ b/test/stage1/behavior/vector.zig
@@ -484,3 +484,43 @@ test "vector shift operators" {
S.doTheTest();
comptime S.doTheTest();
}
+
+test "vector reduce operation" {
+ const S = struct {
+ fn doTheTestReduce(comptime op: builtin.ReduceOp, x: anytype, expected: anytype) void {
+ const N = @typeInfo(@TypeOf(x)).Array.len;
+ const TX = @typeInfo(@TypeOf(x)).Array.child;
+
+ var r = @reduce(op, @as(Vector(N, TX), x));
+ expectEqual(expected, r);
+ }
+ fn doTheTest() void {
+ doTheTestReduce(.And, [4]bool{ true, false, true, true }, @as(bool, false));
+ doTheTestReduce(.Or, [4]bool{ false, true, false, false }, @as(bool, true));
+ doTheTestReduce(.Xor, [4]bool{ true, true, true, false }, @as(bool, true));
+
+ doTheTestReduce(.And, [4]u1{ 1, 0, 1, 1 }, @as(u1, 0));
+ doTheTestReduce(.Or, [4]u1{ 0, 1, 0, 0 }, @as(u1, 1));
+ doTheTestReduce(.Xor, [4]u1{ 1, 1, 1, 0 }, @as(u1, 1));
+
+ doTheTestReduce(.And, [4]u32{ 0xffffffff, 0xffff5555, 0xaaaaffff, 0x10101010 }, @as(u32, 0x1010));
+ doTheTestReduce(.Or, [4]u32{ 0xffff0000, 0xff00, 0xf0, 0xf }, ~@as(u32, 0));
+ doTheTestReduce(.Xor, [4]u32{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, ~@as(u32, 0));
+
+ doTheTestReduce(.Min, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, -386));
+ doTheTestReduce(.Max, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, 1234567));
+
+ doTheTestReduce(.Min, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 9));
+ doTheTestReduce(.Max, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 99999));
+
+ doTheTestReduce(.Min, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, -100.0));
+ doTheTestReduce(.Max, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, 10.0e9));
+
+ doTheTestReduce(.Min, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, -100.0));
+ doTheTestReduce(.Max, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, 10.0e9));
+ }
+ };
+
+ S.doTheTest();
+ comptime S.doTheTest();
+}
diff --git a/test/stage2/arm.zig b/test/stage2/arm.zig
new file mode 100644
index 0000000000..8b15c88552
--- /dev/null
+++ b/test/stage2/arm.zig
@@ -0,0 +1,116 @@
+const std = @import("std");
+const TestContext = @import("../../src/test.zig").TestContext;
+
+const linux_arm = std.zig.CrossTarget{
+ .cpu_arch = .arm,
+ .os_tag = .linux,
+};
+
+pub fn addCases(ctx: *TestContext) !void {
+ {
+ var case = ctx.exe("hello world", linux_arm);
+ // Regular old hello world
+ case.addCompareOutput(
+ \\export fn _start() noreturn {
+ \\ print();
+ \\ exit();
+ \\}
+ \\
+ \\fn print() void {
+ \\ asm volatile ("svc #0"
+ \\ :
+ \\ : [number] "{r7}" (4),
+ \\ [arg1] "{r0}" (1),
+ \\ [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
+ \\ [arg3] "{r2}" (14)
+ \\ : "memory"
+ \\ );
+ \\ return;
+ \\}
+ \\
+ \\fn exit() noreturn {
+ \\ asm volatile ("svc #0"
+ \\ :
+ \\ : [number] "{r7}" (1),
+ \\ [arg1] "{r0}" (0)
+ \\ : "memory"
+ \\ );
+ \\ unreachable;
+ \\}
+ ,
+ "Hello, World!\n",
+ );
+ }
+
+ {
+ var case = ctx.exe("parameters and return values", linux_arm);
+ // Testing simple parameters and return values
+ //
+ // TODO: The parameters to the asm statement in print() had to
+ // be in a specific order because otherwise the write to r0
+ // would overwrite the len parameter which resides in r0
+ case.addCompareOutput(
+ \\export fn _start() noreturn {
+ \\ print(id(14));
+ \\ exit();
+ \\}
+ \\
+ \\fn id(x: u32) u32 {
+ \\ return x;
+ \\}
+ \\
+ \\fn print(len: u32) void {
+ \\ asm volatile ("svc #0"
+ \\ :
+ \\ : [number] "{r7}" (4),
+ \\ [arg3] "{r2}" (len),
+ \\ [arg1] "{r0}" (1),
+ \\ [arg2] "{r1}" (@ptrToInt("Hello, World!\n"))
+ \\ : "memory"
+ \\ );
+ \\ return;
+ \\}
+ \\
+ \\fn exit() noreturn {
+ \\ asm volatile ("svc #0"
+ \\ :
+ \\ : [number] "{r7}" (1),
+ \\ [arg1] "{r0}" (0)
+ \\ : "memory"
+ \\ );
+ \\ unreachable;
+ \\}
+ ,
+ "Hello, World!\n",
+ );
+ }
+
+ {
+ var case = ctx.exe("non-leaf functions", linux_arm);
+ // Testing non-leaf functions
+ case.addCompareOutput(
+ \\export fn _start() noreturn {
+ \\ foo();
+ \\ exit();
+ \\}
+ \\
+ \\fn foo() void {
+ \\ bar();
+ \\}
+ \\
+ \\fn bar() void {}
+ \\
+ \\fn exit() noreturn {
+ \\ asm volatile ("svc #0"
+ \\ :
+ \\ : [number] "{r7}" (1),
+ \\ [arg1] "{r0}" (0)
+ \\ : "memory"
+ \\ );
+ \\ unreachable;
+ \\}
+ ,
+ "",
+ );
+ }
+}
diff --git a/test/stage2/test.zig b/test/stage2/test.zig
index a22dc23d36..2e3b570570 100644
--- a/test/stage2/test.zig
+++ b/test/stage2/test.zig
@@ -21,11 +21,6 @@ const linux_riscv64 = std.zig.CrossTarget{
.os_tag = .linux,
};
-const linux_arm = std.zig.CrossTarget{
- .cpu_arch = .arm,
- .os_tag = .linux,
-};
-
const wasi = std.zig.CrossTarget{
.cpu_arch = .wasm32,
.os_tag = .wasi,
@@ -35,6 +30,7 @@ pub fn addCases(ctx: *TestContext) !void {
try @import("zir.zig").addCases(ctx);
try @import("cbe.zig").addCases(ctx);
try @import("spu-ii.zig").addCases(ctx);
+ try @import("arm.zig").addCases(ctx);
{
var case = ctx.exe("hello world with updates", linux_x64);
@@ -76,7 +72,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"Hello, World!\n",
);
// Now change the message only
@@ -108,7 +104,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"What is up? This is a longer message that will force the data to be relocated in virtual address space.\n",
);
// Now we print it twice.
@@ -151,10 +147,13 @@ pub fn addCases(ctx: *TestContext) !void {
{
var case = ctx.exe("hello world", macosx_x64);
case.addError("", &[_][]const u8{":1:1: error: no entry point found"});
- }
- {
- var case = ctx.exe("hello world", linux_riscv64);
+ // Incorrect return type
+ case.addError(
+ \\export fn _start() noreturn {
+ \\}
+ , &[_][]const u8{":2:1: error: expected noreturn, found void"});
+
// Regular old hello world
case.addCompareOutput(
\\export fn _start() noreturn {
@@ -164,23 +163,23 @@ pub fn addCases(ctx: *TestContext) !void {
\\}
\\
\\fn print() void {
- \\ asm volatile ("ecall"
+ \\ asm volatile ("syscall"
\\ :
- \\ : [number] "{a7}" (64),
- \\ [arg1] "{a0}" (1),
- \\ [arg2] "{a1}" (@ptrToInt("Hello, World!\n")),
- \\ [arg3] "{a2}" ("Hello, World!\n".len)
- \\ : "rcx", "r11", "memory"
+ \\ : [number] "{rax}" (0x2000004),
+ \\ [arg1] "{rdi}" (1),
+ \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
+ \\ [arg3] "{rdx}" (14)
+ \\ : "memory"
\\ );
\\ return;
\\}
\\
\\fn exit() noreturn {
- \\ asm volatile ("ecall"
+ \\ asm volatile ("syscall"
\\ :
- \\ : [number] "{a7}" (94),
- \\ [arg1] "{a0}" (0)
- \\ : "rcx", "r11", "memory"
+ \\ : [number] "{rax}" (0x2000001),
+ \\ [arg1] "{rdi}" (0)
+ \\ : "memory"
\\ );
\\ unreachable;
\\}
@@ -190,36 +189,37 @@ pub fn addCases(ctx: *TestContext) !void {
}
{
- var case = ctx.exe("hello world", linux_arm);
+ var case = ctx.exe("hello world", linux_riscv64);
// Regular old hello world
case.addCompareOutput(
\\export fn _start() noreturn {
\\ print();
+ \\
\\ exit();
\\}
\\
\\fn print() void {
- \\ asm volatile ("svc #0"
+ \\ asm volatile ("ecall"
\\ :
- \\ : [number] "{r7}" (4),
- \\ [arg1] "{r0}" (1),
- \\ [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
- \\ [arg3] "{r2}" (14)
- \\ : "memory"
+ \\ : [number] "{a7}" (64),
+ \\ [arg1] "{a0}" (1),
+ \\ [arg2] "{a1}" (@ptrToInt("Hello, World!\n")),
+ \\ [arg3] "{a2}" ("Hello, World!\n".len)
+ \\ : "rcx", "r11", "memory"
\\ );
\\ return;
\\}
\\
\\fn exit() noreturn {
- \\ asm volatile ("svc #0"
+ \\ asm volatile ("ecall"
\\ :
- \\ : [number] "{r7}" (1),
- \\ [arg1] "{r0}" (0)
- \\ : "memory"
+ \\ : [number] "{a7}" (94),
+ \\ [arg1] "{a0}" (0)
+ \\ : "rcx", "r11", "memory"
\\ );
\\ unreachable;
\\}
- ,
+ ,
"Hello, World!\n",
);
}
@@ -244,7 +244,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"Hello, World!\n",
);
}
@@ -271,7 +271,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
}
@@ -298,7 +298,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
}
@@ -329,7 +329,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -362,7 +362,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -398,7 +398,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -435,7 +435,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -465,7 +465,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -499,7 +499,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -523,7 +523,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -562,7 +562,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"hello\nhello\nhello\nhello\n",
);
@@ -599,7 +599,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -641,7 +641,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -693,7 +693,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -755,7 +755,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -788,7 +788,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -820,7 +820,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -845,7 +845,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -871,7 +871,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"",
);
@@ -904,12 +904,50 @@ pub fn addCases(ctx: *TestContext) !void {
\\ );
\\ unreachable;
\\}
- ,
+ ,
"hello\nhello\nhello\nhello\nhello\n",
);
}
{
+ var case = ctx.exe("basic import", linux_x64);
+ case.addCompareOutput(
+ \\export fn _start() noreturn {
+ \\ @import("print.zig").print();
+ \\ exit();
+ \\}
+ \\
+ \\fn exit() noreturn {
+ \\ asm volatile ("syscall"
+ \\ :
+ \\ : [number] "{rax}" (231),
+ \\ [arg1] "{rdi}" (@as(usize, 0))
+ \\ : "rcx", "r11", "memory"
+ \\ );
+ \\ unreachable;
+ \\}
+ ,
+ "Hello, World!\n",
+ );
+ try case.files.append(.{
+ .src =
+ \\pub fn print() void {
+ \\ asm volatile ("syscall"
+ \\ :
+ \\ : [number] "{rax}" (@as(usize, 1)),
+ \\ [arg1] "{rdi}" (@as(usize, 1)),
+ \\ [arg2] "{rsi}" (@ptrToInt("Hello, World!\n")),
+ \\ [arg3] "{rdx}" (@as(usize, 14))
+ \\ : "rcx", "r11", "memory"
+ \\ );
+ \\ return;
+ \\}
+ ,
+ .path = "print.zig",
+ });
+ }
+
+ {
var case = ctx.exe("wasm function calls", wasi);
case.addCompareOutput(
@@ -923,7 +961,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ bar();
\\}
\\fn bar() void {}
- ,
+ ,
"42\n",
);
@@ -941,7 +979,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ bar();
\\}
\\fn bar() void {}
- ,
+ ,
"42\n",
);
@@ -957,10 +995,10 @@ pub fn addCases(ctx: *TestContext) !void {
\\ bar();
\\}
\\fn bar() void {}
- ,
- // This is what you get when you take the bits of the IEE-754
- // representation of 42.0 and reinterpret them as an unsigned
- // integer. Guess that's a bug in wasmtime.
+ ,
+ // This is what you get when you take the bits of the IEE-754
+ // representation of 42.0 and reinterpret them as an unsigned
+ // integer. Guess that's a bug in wasmtime.
"1109917696\n",
);
}
diff --git a/test/translate_c.zig b/test/translate_c.zig
index 83fdda8d81..4182dbaa13 100644
--- a/test/translate_c.zig
+++ b/test/translate_c.zig
@@ -3,6 +3,22 @@ const std = @import("std");
const CrossTarget = std.zig.CrossTarget;
pub fn addCases(cases: *tests.TranslateCContext) void {
+ cases.add("macro expressions respect C operator precedence",
+ \\#define FOO *((foo) + 2)
+ \\#define VALUE (1 + 2 * 3 + 4 * 5 + 6 << 7 | 8 == 9)
+ \\#define _AL_READ3BYTES(p) ((*(unsigned char *)(p)) \
+ \\ | (*((unsigned char *)(p) + 1) << 8) \
+ \\ | (*((unsigned char *)(p) + 2) << 16))
+ , &[_][]const u8{
+ \\pub const FOO = (foo + 2).*;
+ ,
+ \\pub const VALUE = ((((1 + (2 * 3)) + (4 * 5)) + 6) << 7) | @boolToInt(8 == 9);
+ ,
+ \\pub inline fn _AL_READ3BYTES(p: anytype) @TypeOf(((@import("std").meta.cast([*c]u8, p)).* | (((@import("std").meta.cast([*c]u8, p)) + 1).* << 8)) | (((@import("std").meta.cast([*c]u8, p)) + 2).* << 16)) {
+ \\ return ((@import("std").meta.cast([*c]u8, p)).* | (((@import("std").meta.cast([*c]u8, p)) + 1).* << 8)) | (((@import("std").meta.cast([*c]u8, p)) + 2).* << 16);
+ \\}
+ });
+
cases.add("extern variable in block scope",
\\float bar;
\\int foo() {
@@ -2978,7 +2994,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("string concatenation in macros: three strings",
\\#define FOO "a" "b" "c"
, &[_][]const u8{
- \\pub const FOO = "a" ++ ("b" ++ "c");
+ \\pub const FOO = "a" ++ "b" ++ "c";
});
cases.add("multibyte character literals",