authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-27 15:29:03-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-02-27 15:29:03-05:00
logb5066fdae292f44a6e4c60db9a9db012672dd10e
tree6367bdaa9d4f19ed8905061a670aaff5e6f974f6
parentc03b733f0999418b234067cac51eac0e4412dfe1
parent9f59189c954298fd2be576b7e3dd26388d07751d
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11001 from Vexu/stage2

stage2: make formatted printing work

9 files changed, 87 insertions(+), 25 deletions(-)

lib/std/os/linux.zig+8-2
...@@ -865,10 +865,16 @@ pub fn flock(fd: fd_t, operation: i32) usize {...@@ -865,10 +865,16 @@ pub fn flock(fd: fd_t, operation: i32) usize {
865 return syscall2(.flock, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, operation)));865 return syscall2(.flock, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, operation)));
866}866}
867867
868var vdso_clock_gettime = @ptrCast(?*const anyopaque, init_vdso_clock_gettime);868var vdso_clock_gettime = if (builtin.zig_backend == .stage1)
869 @ptrCast(?*const anyopaque, init_vdso_clock_gettime)
870else
871 @ptrCast(?*const anyopaque, &init_vdso_clock_gettime);
869872
870// We must follow the C calling convention when we call into the VDSO873// We must follow the C calling convention when we call into the VDSO
871const vdso_clock_gettime_ty = fn (i32, *timespec) callconv(.C) usize;874const vdso_clock_gettime_ty = if (builtin.zig_backend == .stage1)
875 fn (i32, *timespec) callconv(.C) usize
876else
877 *const fn (i32, *timespec) callconv(.C) usize;
872878
873pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {879pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
874 if (@hasDecl(VDSO, "CGT_SYM")) {880 if (@hasDecl(VDSO, "CGT_SYM")) {
lib/std/special/test_runner.zig+9-8
...@@ -23,10 +23,12 @@ fn processArgs() void {...@@ -23,10 +23,12 @@ fn processArgs() void {
23}23}
2424
25pub fn main() void {25pub fn main() void {
26 if (builtin.zig_backend != .stage1) {26 if (builtin.zig_backend != .stage1 and
27 builtin.zig_backend != .stage2_llvm)
28 {
27 return main2() catch @panic("test failure");29 return main2() catch @panic("test failure");
28 }30 }
29 processArgs();31 if (builtin.zig_backend == .stage1) processArgs();
30 const test_fn_list = builtin.test_functions;32 const test_fn_list = builtin.test_functions;
31 var ok_count: usize = 0;33 var ok_count: usize = 0;
32 var skip_count: usize = 0;34 var skip_count: usize = 0;
...@@ -44,9 +46,9 @@ pub fn main() void {...@@ -44,9 +46,9 @@ pub fn main() void {
4446
45 var leaks: usize = 0;47 var leaks: usize = 0;
46 for (test_fn_list) |test_fn, i| {48 for (test_fn_list) |test_fn, i| {
47 std.testing.allocator_instance = .{};49 if (builtin.zig_backend != .stage2_llvm) std.testing.allocator_instance = .{};
48 defer {50 defer {
49 if (std.testing.allocator_instance.deinit()) {51 if (builtin.zig_backend != .stage2_llvm and std.testing.allocator_instance.deinit()) {
50 leaks += 1;52 leaks += 1;
51 }53 }
52 }54 }
...@@ -90,9 +92,9 @@ pub fn main() void {...@@ -90,9 +92,9 @@ pub fn main() void {
90 fail_count += 1;92 fail_count += 1;
91 progress.log("FAIL ({s})\n", .{@errorName(err)});93 progress.log("FAIL ({s})\n", .{@errorName(err)});
92 if (!have_tty) std.debug.print("FAIL ({s})\n", .{@errorName(err)});94 if (!have_tty) std.debug.print("FAIL ({s})\n", .{@errorName(err)});
93 if (@errorReturnTrace()) |trace| {95 if (builtin.zig_backend != .stage2_llvm) if (@errorReturnTrace()) |trace| {
94 std.debug.dumpStackTrace(trace.*);96 std.debug.dumpStackTrace(trace.*);
95 }97 };
96 test_node.end();98 test_node.end();
97 },99 },
98 }100 }
...@@ -141,8 +143,7 @@ pub fn main2() anyerror!void {...@@ -141,8 +143,7 @@ pub fn main2() anyerror!void {
141 }143 }
142 };144 };
143 }145 }
144 if (builtin.zig_backend == .stage2_llvm or146 if (builtin.zig_backend == .stage2_wasm or
145 builtin.zig_backend == .stage2_wasm or
146 builtin.zig_backend == .stage2_x86_64)147 builtin.zig_backend == .stage2_x86_64)
147 {148 {
148 const passed = builtin.test_functions.len - skipped - failed;149 const passed = builtin.test_functions.len - skipped - failed;
src/AstGen.zig+8-1
...@@ -244,10 +244,14 @@ pub const ResultLoc = union(enum) {...@@ -244,10 +244,14 @@ pub const ResultLoc = union(enum) {
244 fn strategy(rl: ResultLoc, block_scope: *GenZir) Strategy {244 fn strategy(rl: ResultLoc, block_scope: *GenZir) Strategy {
245 switch (rl) {245 switch (rl) {
246 // In this branch there will not be any store_to_block_ptr instructions.246 // In this branch there will not be any store_to_block_ptr instructions.
247 .discard, .none, .ty, .coerced_ty, .ref => return .{247 .none, .ty, .coerced_ty, .ref => return .{
248 .tag = .break_operand,248 .tag = .break_operand,
249 .elide_store_to_block_ptr_instructions = false,249 .elide_store_to_block_ptr_instructions = false,
250 },250 },
251 .discard => return .{
252 .tag = .break_void,
253 .elide_store_to_block_ptr_instructions = false,
254 },
251 // The pointer got passed through to the sub-expressions, so we will use255 // The pointer got passed through to the sub-expressions, so we will use
252 // break_void here.256 // break_void here.
253 // In this branch there will not be any store_to_block_ptr instructions.257 // In this branch there will not be any store_to_block_ptr instructions.
...@@ -1766,6 +1770,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn...@@ -1766,6 +1770,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
1766 // we assume the result location is written, and we break with void.1770 // we assume the result location is written, and we break with void.
1767 _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);1771 _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
1768 },1772 },
1773 .discard => {
1774 _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
1775 },
1769 else => {1776 else => {
1770 _ = try parent_gz.addBreak(break_tag, block_inst, operand);1777 _ = try parent_gz.addBreak(break_tag, block_inst, operand);
1771 },1778 },
src/Module.zig+1-1
...@@ -3762,7 +3762,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3762,7 +3762,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3762 // Note this resolves the type of the Decl, not the value; if this Decl3762 // Note this resolves the type of the Decl, not the value; if this Decl
3763 // is a struct, for example, this resolves `type` (which needs no resolution),3763 // is a struct, for example, this resolves `type` (which needs no resolution),
3764 // not the struct itself.3764 // not the struct itself.
3765 try sema.resolveTypeLayout(&block_scope, src, decl_tv.ty);3765 try sema.resolveTypeFully(&block_scope, src, decl_tv.ty);
37663766
3767 const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);3767 const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);
37683768
src/Sema.zig+23-9
...@@ -4494,6 +4494,10 @@ fn analyzeCall(...@@ -4494,6 +4494,10 @@ fn analyzeCall(
44944494
4495 try sema.emitBackwardBranch(&child_block, call_src);4495 try sema.emitBackwardBranch(&child_block, call_src);
44964496
4497 // Whether this call should be memoized, set to false if the call can mutate
4498 // comptime state.
4499 var should_memoize = true;
4500
4497 // This will have return instructions analyzed as break instructions to4501 // This will have return instructions analyzed as break instructions to
4498 // the block_inst above. Here we are performing "comptime/inline semantic analysis"4502 // the block_inst above. Here we are performing "comptime/inline semantic analysis"
4499 // for a function body, which means we must map the parameter ZIR instructions to4503 // for a function body, which means we must map the parameter ZIR instructions to
...@@ -4527,6 +4531,7 @@ fn analyzeCall(...@@ -4527,6 +4531,7 @@ fn analyzeCall(
4527 },4531 },
4528 else => {},4532 else => {},
4529 }4533 }
4534 should_memoize = should_memoize and !arg_val.isComptimeMutablePtr();
4530 memoized_call_key.args[arg_i] = .{4535 memoized_call_key.args[arg_i] = .{
4531 .ty = param_ty,4536 .ty = param_ty,
4532 .val = arg_val,4537 .val = arg_val,
...@@ -4552,6 +4557,7 @@ fn analyzeCall(...@@ -4552,6 +4557,7 @@ fn analyzeCall(
4552 },4557 },
4553 else => {},4558 else => {},
4554 }4559 }
4560 should_memoize = should_memoize and !arg_val.isComptimeMutablePtr();
4555 memoized_call_key.args[arg_i] = .{4561 memoized_call_key.args[arg_i] = .{
4556 .ty = sema.typeOf(uncasted_arg),4562 .ty = sema.typeOf(uncasted_arg),
4557 .val = arg_val,4563 .val = arg_val,
...@@ -4597,7 +4603,7 @@ fn analyzeCall(...@@ -4597,7 +4603,7 @@ fn analyzeCall(
4597 // This `res2` is here instead of directly breaking from `res` due to a stage14603 // This `res2` is here instead of directly breaking from `res` due to a stage1
4598 // bug generating invalid LLVM IR.4604 // bug generating invalid LLVM IR.
4599 const res2: Air.Inst.Ref = res2: {4605 const res2: Air.Inst.Ref = res2: {
4600 if (is_comptime_call) {4606 if (should_memoize and is_comptime_call) {
4601 if (mod.memoized_calls.get(memoized_call_key)) |result| {4607 if (mod.memoized_calls.get(memoized_call_key)) |result| {
4602 const ty_inst = try sema.addType(fn_ret_ty);4608 const ty_inst = try sema.addType(fn_ret_ty);
4603 try sema.air_values.append(gpa, result.val);4609 try sema.air_values.append(gpa, result.val);
...@@ -4621,7 +4627,7 @@ fn analyzeCall(...@@ -4621,7 +4627,7 @@ fn analyzeCall(
4621 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);4627 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);
4622 };4628 };
46234629
4624 if (is_comptime_call) {4630 if (should_memoize and is_comptime_call) {
4625 const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result);4631 const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result);
46264632
4627 // TODO: check whether any external comptime memory was mutated by the4633 // TODO: check whether any external comptime memory was mutated by the
...@@ -10975,8 +10981,7 @@ fn zirCondbr(...@@ -10975,8 +10981,7 @@ fn zirCondbr(
1097510981
10976 if (try sema.resolveDefinedValue(parent_block, src, cond)) |cond_val| {10982 if (try sema.resolveDefinedValue(parent_block, src, cond)) |cond_val| {
10977 const body = if (cond_val.toBool()) then_body else else_body;10983 const body = if (cond_val.toBool()) then_body else else_body;
10978 _ = try sema.analyzeBody(parent_block, body);10984 return sema.analyzeBodyInner(parent_block, body);
10979 return always_noreturn;
10980 }10985 }
1098110986
10982 const gpa = sema.gpa;10987 const gpa = sema.gpa;
...@@ -11948,19 +11953,27 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -11948,19 +11953,27 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
11948 var buffer: Value.ToTypeBuffer = undefined;11953 var buffer: Value.ToTypeBuffer = undefined;
11949 const child_ty = child_val.toType(&buffer);11954 const child_ty = child_val.toType(&buffer);
1195011955
11956 const ptr_size = size_val.toEnum(std.builtin.TypeInfo.Pointer.Size);
11957
11958 var actual_sentinel: ?Value = null;
11951 if (!sentinel_val.isNull()) {11959 if (!sentinel_val.isNull()) {
11952 return sema.fail(block, src, "TODO: implement zirReify for pointer with non-null sentinel", .{});11960 if (ptr_size == .One or ptr_size == .C) {
11961 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
11962 }
11963 const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data;
11964 const ptr_ty = try Type.ptr(sema.arena, .{ .@"addrspace" = .generic, .pointee_type = child_ty });
11965 actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
11953 }11966 }
1195411967
11955 const ty = try Type.ptr(sema.arena, .{11968 const ty = try Type.ptr(sema.arena, .{
11956 .size = size_val.toEnum(std.builtin.TypeInfo.Pointer.Size),11969 .size = ptr_size,
11957 .mutable = !is_const_val.toBool(),11970 .mutable = !is_const_val.toBool(),
11958 .@"volatile" = is_volatile_val.toBool(),11971 .@"volatile" = is_volatile_val.toBool(),
11959 .@"align" = @intCast(u8, alignment_val.toUnsignedInt()), // TODO: Validate this value.11972 .@"align" = @intCast(u8, alignment_val.toUnsignedInt()), // TODO: Validate this value.
11960 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),11973 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
11961 .pointee_type = try child_ty.copy(sema.arena),11974 .pointee_type = try child_ty.copy(sema.arena),
11962 .@"allowzero" = is_allowzero_val.toBool(),11975 .@"allowzero" = is_allowzero_val.toBool(),
11963 .sentinel = null,11976 .sentinel = actual_sentinel,
11964 });11977 });
11965 return sema.addType(ty);11978 return sema.addType(ty);
11966 },11979 },
...@@ -12070,6 +12083,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12070,6 +12083,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12070 const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };12083 const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
12071 const type_res = try sema.resolveType(block, src, extra.lhs);12084 const type_res = try sema.resolveType(block, src, extra.lhs);
12072 try sema.checkPtrType(block, type_src, type_res);12085 try sema.checkPtrType(block, type_src, type_res);
12086 _ = try sema.resolveTypeLayout(block, src, type_res.childType());
12073 const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());12087 const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());
1207412088
12075 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {12089 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
...@@ -17587,7 +17601,7 @@ fn resolvePeerTypes(...@@ -17587,7 +17601,7 @@ fn resolvePeerTypes(
17587 return chosen_ty;17601 return chosen_ty;
17588}17602}
1758917603
17590pub fn resolveTypeLayout(17604fn resolveTypeLayout(
17591 sema: *Sema,17605 sema: *Sema,
17592 block: *Block,17606 block: *Block,
17593 src: LazySrcLoc,17607 src: LazySrcLoc,
...@@ -17660,7 +17674,7 @@ fn resolveUnionLayout(...@@ -17660,7 +17674,7 @@ fn resolveUnionLayout(
17660 union_obj.status = .have_layout;17674 union_obj.status = .have_layout;
17661}17675}
1766217676
17663fn resolveTypeFully(17677pub fn resolveTypeFully(
17664 sema: *Sema,17678 sema: *Sema,
17665 block: *Block,17679 block: *Block,
17666 src: LazySrcLoc,17680 src: LazySrcLoc,
src/codegen/llvm.zig+1-1
...@@ -3892,7 +3892,7 @@ pub const FuncGen = struct {...@@ -3892,7 +3892,7 @@ pub const FuncGen = struct {
3892 return self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), "");3892 return self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), "");
3893 }3893 }
38943894
3895 if (operand_ty.zigTypeTag() == .Int and inst_ty.zigTypeTag() == .Pointer) {3895 if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) {
3896 return self.builder.buildIntToPtr(operand, llvm_dest_ty, "");3896 return self.builder.buildIntToPtr(operand, llvm_dest_ty, "");
3897 }3897 }
38983898
src/type.zig+1-1
...@@ -2602,7 +2602,7 @@ pub const Type = extern union {...@@ -2602,7 +2602,7 @@ pub const Type = extern union {
2602 const payload = self.castTag(.pointer).?.data;2602 const payload = self.castTag(.pointer).?.data;
2603 return payload.@"allowzero";2603 return payload.@"allowzero";
2604 },2604 },
2605 else => false,2605 else => return self.zigTypeTag() == .Optional,
2606 };2606 };
2607 }2607 }
26082608
test/behavior.zig+2-2
...@@ -125,6 +125,7 @@ test {...@@ -125,6 +125,7 @@ test {
125 _ = @import("behavior/widening.zig");125 _ = @import("behavior/widening.zig");
126 _ = @import("behavior/bugs/421.zig");126 _ = @import("behavior/bugs/421.zig");
127 _ = @import("behavior/bugs/726.zig");127 _ = @import("behavior/bugs/726.zig");
128 _ = @import("behavior/bugs/828.zig");
128 _ = @import("behavior/bugs/1421.zig");129 _ = @import("behavior/bugs/1421.zig");
129 _ = @import("behavior/bugs/1442.zig");130 _ = @import("behavior/bugs/1442.zig");
130 _ = @import("behavior/bugs/1607.zig");131 _ = @import("behavior/bugs/1607.zig");
...@@ -132,6 +133,7 @@ test {...@@ -132,6 +133,7 @@ test {
132 _ = @import("behavior/bugs/3384.zig");133 _ = @import("behavior/bugs/3384.zig");
133 _ = @import("behavior/bugs/3742.zig");134 _ = @import("behavior/bugs/3742.zig");
134 _ = @import("behavior/bugs/5398.zig");135 _ = @import("behavior/bugs/5398.zig");
136 _ = @import("behavior/bugs/5413.zig");
135 _ = @import("behavior/bugs/5487.zig");137 _ = @import("behavior/bugs/5487.zig");
136 _ = @import("behavior/struct_contains_null_ptr_itself.zig");138 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
137 _ = @import("behavior/switch_prong_err_enum.zig");139 _ = @import("behavior/switch_prong_err_enum.zig");
...@@ -148,12 +150,10 @@ test {...@@ -148,12 +150,10 @@ test {
148 _ = @import("behavior/await_struct.zig");150 _ = @import("behavior/await_struct.zig");
149 _ = @import("behavior/bugs/529.zig");151 _ = @import("behavior/bugs/529.zig");
150 _ = @import("behavior/bugs/718.zig");152 _ = @import("behavior/bugs/718.zig");
151 _ = @import("behavior/bugs/828.zig");
152 _ = @import("behavior/bugs/920.zig");153 _ = @import("behavior/bugs/920.zig");
153 _ = @import("behavior/bugs/1120.zig");154 _ = @import("behavior/bugs/1120.zig");
154 _ = @import("behavior/bugs/1851.zig");155 _ = @import("behavior/bugs/1851.zig");
155 _ = @import("behavior/bugs/3779.zig");156 _ = @import("behavior/bugs/3779.zig");
156 _ = @import("behavior/bugs/5413.zig");
157 _ = @import("behavior/bugs/6456.zig");157 _ = @import("behavior/bugs/6456.zig");
158 _ = @import("behavior/bugs/6781.zig");158 _ = @import("behavior/bugs/6781.zig");
159 _ = @import("behavior/bugs/7003.zig");159 _ = @import("behavior/bugs/7003.zig");
test/behavior/basic.zig+34
...@@ -819,3 +819,37 @@ test "if expression type coercion" {...@@ -819,3 +819,37 @@ test "if expression type coercion" {
819 const x: u16 = if (cond) 1 else 0;819 const x: u16 = if (cond) 1 else 0;
820 try expect(@as(u16, x) == 1);820 try expect(@as(u16, x) == 1);
821}821}
822
823test "discarding the result of various expressions" {
824 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
825 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
826 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
827
828 const S = struct {
829 fn foo() !u32 {
830 return 1;
831 }
832 fn bar() ?u32 {
833 return 1;
834 }
835 };
836 _ = S.bar() orelse {
837 // do nothing
838 };
839 _ = S.foo() catch {
840 // do nothing
841 };
842 _ = switch (1) {
843 1 => 1,
844 2 => {},
845 else => return,
846 };
847 _ = try S.foo();
848 _ = if (S.bar()) |some| some else {};
849 _ = blk: {
850 if (S.bar()) |some| break :blk some;
851 break :blk;
852 };
853 _ = while (S.bar()) |some| break some else {};
854 _ = for ("foo") |char| break char else {};
855}