authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-27 10:27:12-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-07-27 10:27:12-07:00
log90f23e131eadae427c4253fb658002633263b82e
tree805c150d374a3fcacefa7d910a65d1e10a1c2755
parent0527b441ae0e90e0b97052594cabb78129a02782
parent20c230cda955936a04af952f9773c0cdda10d9f4
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #12252 from ziglang/stage3-test-cases

CI: run test-cases with stage3

7 files changed, 85 insertions(+), 87 deletions(-)

ci/zinc/linux_test.sh+3-2
......@@ -62,12 +62,13 @@ stage3/bin/zig build test-fmt -fqemu -fwasmtime -Denable-llvm
6262stage3/bin/zig build test-translate-c -fqemu -fwasmtime -Denable-llvm
6363stage3/bin/zig build test-standalone -fqemu -fwasmtime -Denable-llvm
6464stage3/bin/zig build test-cli -fqemu -fwasmtime -Denable-llvm
65# https://github.com/ziglang/zig/issues/12144
66stage3/bin/zig build test-cases -fqemu -fwasmtime
67stage3/bin/zig build test-link -fqemu -fwasmtime -Denable-llvm
6568
6669$STAGE1_ZIG build test-stack-traces -fqemu -fwasmtime
6770$STAGE1_ZIG build test-run-translated-c -fqemu -fwasmtime
6871$STAGE1_ZIG build docs -fqemu -fwasmtime
69$STAGE1_ZIG build test-cases -fqemu -fwasmtime
70$STAGE1_ZIG build test-link -fqemu -fwasmtime
7172
7273# Produce the experimental std lib documentation.
7374mkdir -p "$RELEASE_STAGING/docs/std"
lib/std/start.zig-4
......@@ -455,10 +455,6 @@ fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 {
455455 std.os.argv = argv[0..argc];
456456 std.os.environ = envp;
457457
458 if (builtin.zig_backend == .stage2_llvm) {
459 return @call(.{ .modifier = .always_inline }, callMain, .{});
460 }
461
462458 std.debug.maybeEnableSegfaultHandler();
463459
464460 return initEventLoopAndCallMain();
src/codegen/llvm.zig+15-4
......@@ -673,6 +673,7 @@ pub const Object = struct {
673673 ) !void {
674674 const decl_index = func.owner_decl;
675675 const decl = module.declPtr(decl_index);
676 const target = module.getTarget();
676677
677678 var dg: DeclGen = .{
678679 .context = o.context,
......@@ -706,6 +707,17 @@ pub const Object = struct {
706707 DeclGen.removeFnAttr(llvm_func, "noinline");
707708 }
708709
710 // TODO: port these over from stage1
711 // addLLVMFnAttr(llvm_fn, "sspstrong");
712 // addLLVMFnAttrStr(llvm_fn, "stack-protector-buffer-size", "4");
713
714 // TODO: disable this if safety is off for the function scope
715 if (module.comp.bin_file.options.stack_check) {
716 dg.addFnAttrString(llvm_func, "probe-stack", "__zig_probe_stack");
717 } else if (target.os.tag == .uefi) {
718 dg.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
719 }
720
709721 // Remove all the basic blocks of a function in order to start over, generating
710722 // LLVM IR from an empty function body.
711723 while (llvm_func.getFirstBasicBlock()) |bb| {
......@@ -719,7 +731,6 @@ pub const Object = struct {
719731
720732 // This gets the LLVM values from the function and stores them in `dg.args`.
721733 const fn_info = decl.ty.fnInfo();
722 const target = dg.module.getTarget();
723734 const sret = firstParamSRet(fn_info, target);
724735 const ret_ptr = if (sret) llvm_func.getParam(0) else null;
725736 const gpa = dg.gpa;
......@@ -730,7 +741,7 @@ pub const Object = struct {
730741 };
731742
732743 const err_return_tracing = fn_info.return_type.isError() and
733 dg.module.comp.bin_file.options.error_return_tracing;
744 module.comp.bin_file.options.error_return_tracing;
734745
735746 const err_ret_trace = if (err_return_tracing)
736747 llvm_func.getParam(@boolToInt(ret_ptr != null))
......@@ -920,7 +931,7 @@ pub const Object = struct {
920931
921932 const line_number = decl.src_line + 1;
922933 const is_internal_linkage = decl.val.tag() != .extern_fn and
923 !dg.module.decl_exports.contains(decl_index);
934 !module.decl_exports.contains(decl_index);
924935 const noret_bit: c_uint = if (fn_info.return_type.isNoReturn())
925936 llvm.DIFlags.NoReturn
926937 else
......@@ -936,7 +947,7 @@ pub const Object = struct {
936947 true, // is definition
937948 line_number + func.lbrace_line, // scope line
938949 llvm.DIFlags.StaticMember | noret_bit,
939 dg.module.comp.bin_file.options.optimize_mode != .Debug,
950 module.comp.bin_file.options.optimize_mode != .Debug,
940951 null, // decl_subprogram
941952 );
942953 try dg.object.di_map.put(gpa, decl, subprogram.toNode());
src/link/C.zig+46-29
......@@ -263,11 +263,13 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
263263 // Covers zig.h and err_typedef_item.
264264 try f.all_buffers.ensureUnusedCapacity(gpa, 2);
265265
266 f.all_buffers.appendAssumeCapacity(.{
267 .iov_base = zig_h,
268 .iov_len = zig_h.len,
269 });
270 f.file_size += zig_h.len;
266 if (zig_h.len != 0) {
267 f.all_buffers.appendAssumeCapacity(.{
268 .iov_base = zig_h,
269 .iov_len = zig_h.len,
270 });
271 f.file_size += zig_h.len;
272 }
271273
272274 const err_typedef_writer = f.err_typedef_buf.writer(gpa);
273275 const err_typedef_index = f.all_buffers.items.len;
......@@ -301,11 +303,18 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
301303 try flushDecl(self, &f, decl_index);
302304 }
303305
304 f.all_buffers.items[err_typedef_index] = .{
305 .iov_base = f.err_typedef_buf.items.ptr,
306 .iov_len = f.err_typedef_buf.items.len,
307 };
308 f.file_size += f.err_typedef_buf.items.len;
306 if (f.err_typedef_buf.items.len == 0) {
307 f.all_buffers.items[err_typedef_index] = .{
308 .iov_base = "",
309 .iov_len = 0,
310 };
311 } else {
312 f.all_buffers.items[err_typedef_index] = .{
313 .iov_base = f.err_typedef_buf.items.ptr,
314 .iov_len = f.err_typedef_buf.items.len,
315 };
316 f.file_size += f.err_typedef_buf.items.len;
317 }
309318
310319 // Now the function bodies.
311320 try f.all_buffers.ensureUnusedCapacity(gpa, f.fn_count);
......@@ -391,21 +400,25 @@ fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError!
391400
392401 if (decl_block.fwd_decl.items.len != 0) {
393402 const buf = decl_block.fwd_decl.items;
394 try f.all_buffers.append(gpa, .{
395 .iov_base = buf.ptr,
396 .iov_len = buf.len,
397 });
398 f.file_size += buf.len;
403 if (buf.len != 0) {
404 try f.all_buffers.append(gpa, .{
405 .iov_base = buf.ptr,
406 .iov_len = buf.len,
407 });
408 f.file_size += buf.len;
409 }
399410 }
400411 if (decl.getFunction() != null) {
401412 f.fn_count += 1;
402413 } else if (decl_block.code.items.len != 0) {
403414 const buf = decl_block.code.items;
404 try f.all_buffers.append(gpa, .{
405 .iov_base = buf.ptr,
406 .iov_len = buf.len,
407 });
408 f.file_size += buf.len;
415 if (buf.len != 0) {
416 try f.all_buffers.append(gpa, .{
417 .iov_base = buf.ptr,
418 .iov_len = buf.len,
419 });
420 f.file_size += buf.len;
421 }
409422 }
410423}
411424
......@@ -421,19 +434,23 @@ pub fn flushEmitH(module: *Module) !void {
421434 defer all_buffers.deinit();
422435
423436 var file_size: u64 = zig_h.len;
424 all_buffers.appendAssumeCapacity(.{
425 .iov_base = zig_h,
426 .iov_len = zig_h.len,
427 });
437 if (zig_h.len != 0) {
438 all_buffers.appendAssumeCapacity(.{
439 .iov_base = zig_h,
440 .iov_len = zig_h.len,
441 });
442 }
428443
429444 for (emit_h.decl_table.keys()) |decl_index| {
430445 const decl_emit_h = emit_h.declPtr(decl_index);
431446 const buf = decl_emit_h.fwd_decl.items;
432 all_buffers.appendAssumeCapacity(.{
433 .iov_base = buf.ptr,
434 .iov_len = buf.len,
435 });
436 file_size += buf.len;
447 if (buf.len != 0) {
448 all_buffers.appendAssumeCapacity(.{
449 .iov_base = buf.ptr,
450 .iov_len = buf.len,
451 });
452 file_size += buf.len;
453 }
437454 }
438455
439456 const directory = emit_h.loc.directory orelse module.comp.local_cache_directory;
src/link/Dwarf.zig+2-2
......@@ -1752,7 +1752,7 @@ fn pwriteDbgLineNops(
17521752 .iov_base = buf.ptr,
17531753 .iov_len = buf.len,
17541754 };
1755 vec_index += 1;
1755 if (buf.len > 0) vec_index += 1;
17561756
17571757 {
17581758 var padding_left = next_padding_size;
......@@ -1861,7 +1861,7 @@ fn pwriteDbgInfoNops(
18611861 .iov_base = buf.ptr,
18621862 .iov_len = buf.len,
18631863 };
1864 vec_index += 1;
1864 if (buf.len > 0) vec_index += 1;
18651865
18661866 {
18671867 var padding_left = next_padding_size;
src/test.zig+19-31
......@@ -20,7 +20,7 @@ const enable_wasmtime: bool = build_options.enable_wasmtime;
2020const enable_darling: bool = build_options.enable_darling;
2121const enable_rosetta: bool = build_options.enable_rosetta;
2222const glibc_runtimes_dir: ?[]const u8 = build_options.glibc_runtimes_dir;
23const skip_stage1 = build_options.skip_stage1;
23const skip_stage1 = builtin.zig_backend != .stage1 or build_options.skip_stage1;
2424
2525const hr = "=" ** 80;
2626
......@@ -233,11 +233,11 @@ const TestManifest = struct {
233233 fn ConfigValueIterator(comptime T: type) type {
234234 return struct {
235235 inner: std.mem.SplitIterator(u8),
236 parse_fn: ParseFn(T),
237236
238237 fn next(self: *@This()) !?T {
239238 const next_raw = self.inner.next() orelse return null;
240 return try self.parse_fn(next_raw);
239 const parseFn = getDefaultParser(T);
240 return try parseFn(next_raw);
241241 }
242242 };
243243 }
......@@ -313,27 +313,17 @@ const TestManifest = struct {
313313 return manifest;
314314 }
315315
316 fn getConfigForKeyCustomParser(
316 fn getConfigForKey(
317317 self: TestManifest,
318318 key: []const u8,
319319 comptime T: type,
320 parse_fn: ParseFn(T),
321320 ) ConfigValueIterator(T) {
322321 const bytes = self.config_map.get(key) orelse TestManifestConfigDefaults.get(self.@"type", key);
323322 return ConfigValueIterator(T){
324323 .inner = std.mem.split(u8, bytes, ","),
325 .parse_fn = parse_fn,
326324 };
327325 }
328326
329 fn getConfigForKey(
330 self: TestManifest,
331 key: []const u8,
332 comptime T: type,
333 ) ConfigValueIterator(T) {
334 return self.getConfigForKeyCustomParser(key, T, getDefaultParser(T));
335 }
336
337327 fn getConfigForKeyAlloc(
338328 self: TestManifest,
339329 allocator: Allocator,
......@@ -377,6 +367,15 @@ const TestManifest = struct {
377367 }
378368
379369 fn getDefaultParser(comptime T: type) ParseFn(T) {
370 if (T == CrossTarget) return struct {
371 fn parse(str: []const u8) anyerror!T {
372 var opts = CrossTarget.ParseOptions{
373 .arch_os_abi = str,
374 };
375 return try CrossTarget.parse(opts);
376 }
377 }.parse;
378
380379 switch (@typeInfo(T)) {
381380 .Int => return struct {
382381 fn parse(str: []const u8) anyerror!T {
......@@ -397,14 +396,7 @@ const TestManifest = struct {
397396 };
398397 }
399398 }.parse,
400 .Struct => if (comptime std.mem.eql(u8, @typeName(T), "CrossTarget")) return struct {
401 fn parse(str: []const u8) anyerror!T {
402 var opts = CrossTarget.ParseOptions{
403 .arch_os_abi = str,
404 };
405 return try CrossTarget.parse(opts);
406 }
407 }.parse else @compileError("no default parser for " ++ @typeName(T)),
399 .Struct => @compileError("no default parser for " ++ @typeName(T)),
408400 else => @compileError("no default parser for " ++ @typeName(T)),
409401 }
410402 }
......@@ -884,8 +876,6 @@ pub const TestContext = struct {
884876 src: [:0]const u8,
885877 expected_errors: []const []const u8,
886878 ) void {
887 if (skip_stage1) return;
888
889879 const case = ctx.addObj(name, .{});
890880 case.backend = .stage1;
891881 case.addError(src, expected_errors);
......@@ -897,8 +887,6 @@ pub const TestContext = struct {
897887 src: [:0]const u8,
898888 expected_errors: []const []const u8,
899889 ) void {
900 if (skip_stage1) return;
901
902890 const case = ctx.addTest(name, .{});
903891 case.backend = .stage1;
904892 case.addError(src, expected_errors);
......@@ -910,8 +898,6 @@ pub const TestContext = struct {
910898 src: [:0]const u8,
911899 expected_errors: []const []const u8,
912900 ) void {
913 if (skip_stage1) return;
914
915901 const case = ctx.addExe(name, .{});
916902 case.backend = .stage1;
917903 case.addError(src, expected_errors);
......@@ -1143,8 +1129,6 @@ pub const TestContext = struct {
11431129
11441130 // Cross-product to get all possible test combinations
11451131 for (backends) |backend| {
1146 if (backend == .stage1 and skip_stage1) continue;
1147
11481132 for (targets) |target| {
11491133 const name = try std.fmt.allocPrint(ctx.arena, "{s} ({s}, {s})", .{
11501134 name_prefix,
......@@ -1276,6 +1260,9 @@ pub const TestContext = struct {
12761260 if (!build_options.have_llvm and case.backend == .llvm)
12771261 continue;
12781262
1263 if (skip_stage1 and case.backend == .stage1)
1264 continue;
1265
12791266 if (build_options.test_filter) |test_filter| {
12801267 if (std.mem.indexOf(u8, case.name, test_filter) == null) continue;
12811268 }
......@@ -1607,6 +1594,7 @@ pub const TestContext = struct {
16071594
16081595 var module_node = update_node.start("parse/analysis/codegen", 0);
16091596 module_node.activate();
1597 module_node.context.refresh();
16101598 try comp.makeBinFileWritable();
16111599 try comp.update();
16121600 module_node.end();
......@@ -1855,7 +1843,7 @@ pub const TestContext = struct {
18551843
18561844 .qemu => |qemu_bin_name| if (enable_qemu) {
18571845 const need_cross_glibc = target.isGnuLibC() and case.link_libc;
1858 const glibc_dir_arg = if (need_cross_glibc)
1846 const glibc_dir_arg: ?[]const u8 = if (need_cross_glibc)
18591847 glibc_runtimes_dir orelse continue :update // glibc dir not available; pass test
18601848 else
18611849 null;
test/cases/compile_errors/endless_loop_in_function_evaluation.zig deleted-15
......@@ -1,15 +0,0 @@
1const seventh_fib_number = fibonacci(7);
2fn fibonacci(x: i32) i32 {
3 return fibonacci(x - 1) + fibonacci(x - 2);
4}
5
6export fn entry() usize { return @sizeOf(@TypeOf(&seventh_fib_number)); }
7
8// error
9// backend=stage2
10// target=native
11//
12// :3:21: error: evaluation exceeded 1000 backwards branches
13// :3:21: note: use @setEvalBranchQuota() to raise the branch limit from 1000
14// :3:21: note: called from here (999 times)
15// :1:37: note: called from here