diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-10-07 00:46:05 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-10-07 00:46:05 -0700 |
| commit | b5a36f676b1fd69f195d9f1eb6e35f3eb2f15946 (patch) | |
| tree | 92ce1ffa64bc2d32d5ef73dce66daf3c8e893ee6 /test | |
| parent | d6d05fc84d33c71434a1f8bae51ca5956e08cdf0 (diff) | |
| parent | f2d374e8465042fa5cb6bf2be7b9b086948f3a94 (diff) | |
| download | zig-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.zig | 229 | ||||
| -rw-r--r-- | test/stage1/behavior/bugs/1467.zig | 7 | ||||
| -rw-r--r-- | test/stage1/behavior/type.zig | 43 | ||||
| -rw-r--r-- | test/stage1/behavior/type_info.zig | 21 | ||||
| -rw-r--r-- | test/stage1/behavior/vector.zig | 40 | ||||
| -rw-r--r-- | test/stage2/arm.zig | 116 | ||||
| -rw-r--r-- | test/stage2/test.zig | 154 | ||||
| -rw-r--r-- | test/translate_c.zig | 18 |
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", |
