| author | |
| committer | |
| log | 9ccf8d3332dd9c1e4d967e3b8af2b98128d360ca |
| tree | f0c010eaa7d6133d550e004ed0ee6809619cd34f |
| parent | 4f8d244e7ea47a8cdb41496d51961ef4ba3ec2af |
I had to bring back some of the old API so that I could compile the new
compiler with an old compiler.5 files changed, 152 insertions(+), 75 deletions(-)
lib/std/builtin.zig+75-2| ... | ... | @@ -761,18 +761,91 @@ pub const TestFn = struct { |
| 761 | 761 | func: *const fn () anyerror!void, |
| 762 | 762 | }; |
| 763 | 763 | |
| 764 | const old_version = std.SemanticVersion.parse("0.14.0-dev.1659+4ceefca14") catch unreachable; | |
| 765 | const is_old = @import("builtin").zig_version.order(old_version) != .gt; | |
| 766 | ||
| 764 | 767 | /// This function type is used by the Zig language code generation and |
| 765 | 768 | /// therefore must be kept in sync with the compiler implementation. |
| 766 | pub const PanicFn = fn (PanicCause, ?*StackTrace, ?usize) noreturn; | |
| 769 | pub const PanicFn = if (is_old) | |
| 770 | fn ([]const u8, ?*StackTrace, ?usize) noreturn | |
| 771 | else | |
| 772 | fn (PanicCause, ?*StackTrace, ?usize) noreturn; | |
| 767 | 773 | |
| 768 | 774 | /// The entry point for auto-generated calls by the compiler. |
| 769 | pub const panic: PanicFn = if (@hasDecl(root, "panic")) | |
| 775 | pub const panic: PanicFn = if (is_old) | |
| 776 | defaultPanicOld | |
| 777 | else if (@hasDecl(root, "panic")) | |
| 770 | 778 | root.panic |
| 771 | 779 | else if (@hasDecl(root, "os") and @hasDecl(root.os, "panic")) |
| 772 | 780 | root.os.panic |
| 773 | 781 | else |
| 774 | 782 | std.debug.defaultPanic; |
| 775 | 783 | |
| 784 | pub fn defaultPanicOld( | |
| 785 | msg: []const u8, | |
| 786 | trace: ?*const std.builtin.StackTrace, | |
| 787 | first_trace_addr: ?usize, | |
| 788 | ) noreturn { | |
| 789 | @branchHint(.cold); | |
| 790 | std.debug.print("old panic: {s}\n", .{msg}); | |
| 791 | _ = trace; | |
| 792 | _ = first_trace_addr; | |
| 793 | @trap(); | |
| 794 | } | |
| 795 | ||
| 796 | pub fn panicSentinelMismatch(expected: anytype, actual: @TypeOf(expected)) noreturn { | |
| 797 | @branchHint(.cold); | |
| 798 | std.debug.panicExtra(null, @returnAddress(), "sentinel mismatch: expected {any}, found {any}", .{ expected, actual }); | |
| 799 | } | |
| 800 | ||
| 801 | pub fn panicUnwrapError(st: ?*StackTrace, err: anyerror) noreturn { | |
| 802 | @branchHint(.cold); | |
| 803 | std.debug.panicExtra(st, @returnAddress(), "attempt to unwrap error: {s}", .{@errorName(err)}); | |
| 804 | } | |
| 805 | ||
| 806 | pub fn panicOutOfBounds(index: usize, len: usize) noreturn { | |
| 807 | @branchHint(.cold); | |
| 808 | std.debug.panicExtra(null, @returnAddress(), "index out of bounds: index {d}, len {d}", .{ index, len }); | |
| 809 | } | |
| 810 | ||
| 811 | pub fn panicStartGreaterThanEnd(start: usize, end: usize) noreturn { | |
| 812 | @branchHint(.cold); | |
| 813 | std.debug.panicExtra(null, @returnAddress(), "start index {d} is larger than end index {d}", .{ start, end }); | |
| 814 | } | |
| 815 | ||
| 816 | pub fn panicInactiveUnionField(active: anytype, wanted: @TypeOf(active)) noreturn { | |
| 817 | @branchHint(.cold); | |
| 818 | std.debug.panicExtra(null, @returnAddress(), "access of union field '{s}' while field '{s}' is active", .{ @tagName(wanted), @tagName(active) }); | |
| 819 | } | |
| 820 | ||
| 821 | pub const panic_messages = struct { | |
| 822 | pub const unreach = "reached unreachable code"; | |
| 823 | pub const unwrap_null = "attempt to use null value"; | |
| 824 | pub const cast_to_null = "cast causes pointer to be null"; | |
| 825 | pub const incorrect_alignment = "incorrect alignment"; | |
| 826 | pub const invalid_error_code = "invalid error code"; | |
| 827 | pub const cast_truncated_data = "integer cast truncated bits"; | |
| 828 | pub const negative_to_unsigned = "attempt to cast negative value to unsigned integer"; | |
| 829 | pub const integer_overflow = "integer overflow"; | |
| 830 | pub const shl_overflow = "left shift overflowed bits"; | |
| 831 | pub const shr_overflow = "right shift overflowed bits"; | |
| 832 | pub const divide_by_zero = "division by zero"; | |
| 833 | pub const exact_division_remainder = "exact division produced remainder"; | |
| 834 | pub const inactive_union_field = "access of inactive union field"; | |
| 835 | pub const integer_part_out_of_bounds = "integer part of floating point value out of bounds"; | |
| 836 | pub const corrupt_switch = "switch on corrupt value"; | |
| 837 | pub const shift_rhs_too_big = "shift amount is greater than the type size"; | |
| 838 | pub const invalid_enum_value = "invalid enum value"; | |
| 839 | pub const sentinel_mismatch = "sentinel mismatch"; | |
| 840 | pub const unwrap_error = "attempt to unwrap error"; | |
| 841 | pub const index_out_of_bounds = "index out of bounds"; | |
| 842 | pub const start_index_greater_than_end = "start index is larger than end index"; | |
| 843 | pub const for_len_mismatch = "for loop over objects with non-equal lengths"; | |
| 844 | pub const memcpy_len_mismatch = "@memcpy arguments have non-equal lengths"; | |
| 845 | pub const memcpy_alias = "@memcpy arguments alias"; | |
| 846 | pub const noreturn_returned = "'noreturn' function returned"; | |
| 847 | }; | |
| 848 | ||
| 776 | 849 | /// This data structure is used by the Zig language code generation and |
| 777 | 850 | /// therefore must be kept in sync with the compiler implementation. |
| 778 | 851 | pub const PanicCause = union(enum) { |
lib/std/debug.zig+3-15| ... | ... | @@ -437,7 +437,7 @@ pub fn panicExtra( |
| 437 | 437 | break :blk &buf; |
| 438 | 438 | }, |
| 439 | 439 | }; |
| 440 | std.builtin.panic(msg, trace, ret_addr); | |
| 440 | std.builtin.panic(.{ .explicit_call = msg }, trace, ret_addr); | |
| 441 | 441 | } |
| 442 | 442 | |
| 443 | 443 | /// Non-zero whenever the program triggered a panic. |
| ... | ... | @@ -487,18 +487,6 @@ pub fn defaultPanic( |
| 487 | 487 | .freestanding => { |
| 488 | 488 | @trap(); |
| 489 | 489 | }, |
| 490 | .wasi => { | |
| 491 | // TODO: before merging my branch, unify this logic with the main panic logic | |
| 492 | var buffer: [1000]u8 = undefined; | |
| 493 | var i: usize = 0; | |
| 494 | i += fmtPanicCause(buffer[i..], cause); | |
| 495 | buffer[i] = '\n'; | |
| 496 | i += 1; | |
| 497 | const msg = buffer[0..i]; | |
| 498 | lockStdErr(); | |
| 499 | io.getStdErr().writeAll(msg) catch {}; | |
| 500 | @trap(); | |
| 501 | }, | |
| 502 | 490 | .uefi => { |
| 503 | 491 | const uefi = std.os.uefi; |
| 504 | 492 | |
| ... | ... | @@ -571,7 +559,7 @@ pub fn defaultPanic( |
| 571 | 559 | i += fmtInt10(buffer[i..], std.Thread.getCurrentId()); |
| 572 | 560 | i += fmtBuf(buffer[i..], " panic: "); |
| 573 | 561 | } |
| 574 | i += fmtPanicCause(&buffer, cause); | |
| 562 | i += fmtPanicCause(buffer[i..], cause); | |
| 575 | 563 | buffer[i] = '\n'; |
| 576 | 564 | i += 1; |
| 577 | 565 | const msg = buffer[0..i]; |
| ... | ... | @@ -672,7 +660,7 @@ fn fmtInt10(out_buf: []u8, integer_value: usize) usize { |
| 672 | 660 | |
| 673 | 661 | while (true) { |
| 674 | 662 | i -= 1; |
| 675 | tmp_buf[i] = '0' + (a % 10); | |
| 663 | tmp_buf[i] = '0' + @as(u8, @intCast(a % 10)); | |
| 676 | 664 | a /= 10; |
| 677 | 665 | if (a == 0) break; |
| 678 | 666 | } |
src/Sema.zig+18-10| ... | ... | @@ -2566,7 +2566,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg |
| 2566 | 2566 | std.debug.print("compile error during Sema:\n", .{}); |
| 2567 | 2567 | var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory"); |
| 2568 | 2568 | error_bundle.renderToStdErr(.{ .ttyconf = .no_color }); |
| 2569 | crash_report.compilerPanic("unexpected compile error occurred", null, null); | |
| 2569 | crash_report.compilerPanic(.{ .explicit_call = "unexpected compile error occurred" }, null, null); | |
| 2570 | 2570 | } |
| 2571 | 2571 | |
| 2572 | 2572 | if (block) |start_block| { |
| ... | ... | @@ -7334,17 +7334,21 @@ fn callPanic( |
| 7334 | 7334 | call_operation: CallOperation, |
| 7335 | 7335 | ) !void { |
| 7336 | 7336 | const pt = sema.pt; |
| 7337 | if (!pt.zcu.backendSupportsFeature(.panic_fn)) { | |
| 7337 | const zcu = pt.zcu; | |
| 7338 | if (!zcu.backendSupportsFeature(.panic_fn)) { | |
| 7338 | 7339 | _ = try block.addNoOp(.trap); |
| 7339 | 7340 | return; |
| 7340 | 7341 | } |
| 7341 | 7342 | const panic_cause_ty = try pt.getBuiltinType("PanicCause"); |
| 7342 | const panic_cause = try block.addUnionInit(panic_cause_ty, @intFromEnum(tag), payload); | |
| 7343 | const panic_cause = if (payload == .void_value) | |
| 7344 | try initUnionFromEnumTag(pt, panic_cause_ty, panic_cause_ty.unionTagType(zcu).?, @intFromEnum(tag)) | |
| 7345 | else | |
| 7346 | try block.addUnionInit(panic_cause_ty, @intFromEnum(tag), payload); | |
| 7343 | 7347 | const panic_fn = try pt.getBuiltin("panic"); |
| 7344 | 7348 | const err_return_trace = try sema.getErrorReturnTrace(block); |
| 7345 | 7349 | const opt_usize_ty = try pt.optionalType(.usize_type); |
| 7346 | 7350 | const null_usize = try pt.nullValue(opt_usize_ty); |
| 7347 | const args: [3]Air.Inst.Ref = .{ panic_cause, err_return_trace, Air.internedToRef(null_usize) }; | |
| 7351 | const args: [3]Air.Inst.Ref = .{ panic_cause, err_return_trace, Air.internedToRef(null_usize.toIntern()) }; | |
| 7348 | 7352 | try sema.callBuiltin(block, call_src, panic_fn, .auto, &args, call_operation); |
| 7349 | 7353 | } |
| 7350 | 7354 | |
| ... | ... | @@ -18326,11 +18330,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18326 | 18330 | .undefined, |
| 18327 | 18331 | .null, |
| 18328 | 18332 | .enum_literal, |
| 18329 | => |type_info_tag| return Air.internedToRef((try pt.internUnion(.{ | |
| 18330 | .ty = type_info_ty.toIntern(), | |
| 18331 | .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(type_info_tag))).toIntern(), | |
| 18332 | .val = .void_value, | |
| 18333 | }))), | |
| 18333 | => |type_info_tag| return initUnionFromEnumTag(pt, type_info_ty, type_info_tag_ty, @intFromEnum(type_info_tag)), | |
| 18334 | 18334 | .@"fn" => { |
| 18335 | 18335 | const fn_info_ty = try getInnerType(sema, block, src, type_info_ty, "Fn"); |
| 18336 | 18336 | const param_info_ty = try getInnerType(sema, block, src, fn_info_ty, "Param"); |
| ... | ... | @@ -28009,7 +28009,7 @@ fn addSafetyCheckSentinelMismatch( |
| 28009 | 28009 | assert(std.mem.eql(u8, fields[1].name, "found")); |
| 28010 | 28010 | assert(fields.len == 2); |
| 28011 | 28011 | } |
| 28012 | const panic_cause_payload = &fail_block.addAggregateInit(mm_ty, &.{ expected_sentinel, actual_sentinel }); | |
| 28012 | const panic_cause_payload = try fail_block.addAggregateInit(mm_ty, &.{ expected_sentinel, actual_sentinel }); | |
| 28013 | 28013 | try callPanic(sema, &fail_block, src, .sentinel_mismatch_usize, panic_cause_payload, .@"safety check"); |
| 28014 | 28014 | } else { |
| 28015 | 28015 | try callPanic(sema, &fail_block, src, .sentinel_mismatch_other, .void_value, .@"safety check"); |
| ... | ... | @@ -38997,3 +38997,11 @@ fn getInnerType( |
| 38997 | 38997 | try sema.ensureNavResolved(src, nav); |
| 38998 | 38998 | return Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 38999 | 38999 | } |
| 39000 | ||
| 39001 | fn initUnionFromEnumTag(pt: Zcu.PerThread, union_ty: Type, union_tag_ty: Type, field_index: u32) !Air.Inst.Ref { | |
| 39002 | return Air.internedToRef((try pt.internUnion(.{ | |
| 39003 | .ty = union_ty.toIntern(), | |
| 39004 | .tag = (try pt.enumValueFieldIndex(union_tag_ty, field_index)).toIntern(), | |
| 39005 | .val = .void_value, | |
| 39006 | }))); | |
| 39007 | } |
src/codegen/llvm.zig+49-44| ... | ... | @@ -3848,13 +3848,13 @@ pub const Object = struct { |
| 3848 | 3848 | |
| 3849 | 3849 | .undef => unreachable, // handled above |
| 3850 | 3850 | .simple_value => |simple_value| switch (simple_value) { |
| 3851 | .undefined, | |
| 3852 | .void, | |
| 3853 | .null, | |
| 3854 | .empty_struct, | |
| 3855 | .@"unreachable", | |
| 3856 | .generic_poison, | |
| 3857 | => unreachable, // non-runtime values | |
| 3851 | .undefined => unreachable, // non-runtime value | |
| 3852 | .void => unreachable, // non-runtime value | |
| 3853 | .null => unreachable, // non-runtime value | |
| 3854 | .empty_struct => unreachable, // non-runtime value | |
| 3855 | .@"unreachable" => unreachable, // non-runtime value | |
| 3856 | .generic_poison => unreachable, // non-runtime value | |
| 3857 | ||
| 3858 | 3858 | .false => .false, |
| 3859 | 3859 | .true => .true, |
| 3860 | 3860 | }, |
| ... | ... | @@ -5675,43 +5675,48 @@ pub const FuncGen = struct { |
| 5675 | 5675 | } |
| 5676 | 5676 | } |
| 5677 | 5677 | |
| 5678 | fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.PanicId) !void { | |
| 5679 | const o = fg.ng.object; | |
| 5680 | const zcu = o.pt.zcu; | |
| 5681 | const ip = &zcu.intern_pool; | |
| 5682 | const msg_nav_index = zcu.panic_messages[@intFromEnum(panic_id)].unwrap().?; | |
| 5683 | const msg_nav = ip.getNav(msg_nav_index); | |
| 5684 | const msg_len = Type.fromInterned(msg_nav.typeOf(ip)).childType(zcu).arrayLen(zcu); | |
| 5685 | const msg_ptr = try o.lowerValue(msg_nav.status.resolved.val); | |
| 5686 | const null_opt_addr_global = try fg.resolveNullOptUsize(); | |
| 5687 | const target = zcu.getTarget(); | |
| 5688 | const llvm_usize = try o.lowerType(Type.usize); | |
| 5689 | // example: | |
| 5690 | // call fastcc void @test2.panic( | |
| 5691 | // ptr @builtin.panic_messages.integer_overflow__anon_987, ; msg.ptr | |
| 5692 | // i64 16, ; msg.len | |
| 5693 | // ptr null, ; stack trace | |
| 5694 | // ptr @2, ; addr (null ?usize) | |
| 5695 | // ) | |
| 5696 | const panic_func = zcu.funcInfo(zcu.panic_func_index); | |
| 5697 | const panic_nav = ip.getNav(panic_func.owner_nav); | |
| 5698 | const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?; | |
| 5699 | const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav); | |
| 5700 | _ = try fg.wip.callIntrinsicAssumeCold(); | |
| 5701 | _ = try fg.wip.call( | |
| 5702 | .normal, | |
| 5703 | toLlvmCallConv(fn_info.cc, target), | |
| 5704 | .none, | |
| 5705 | panic_global.typeOf(&o.builder), | |
| 5706 | panic_global.toValue(&o.builder), | |
| 5707 | &.{ | |
| 5708 | msg_ptr.toValue(), | |
| 5709 | try o.builder.intValue(llvm_usize, msg_len), | |
| 5710 | try o.builder.nullValue(.ptr), | |
| 5711 | null_opt_addr_global.toValue(), | |
| 5712 | }, | |
| 5713 | "", | |
| 5714 | ); | |
| 5678 | const PanicCauseTag = @typeInfo(std.builtin.PanicCause).@"union".tag_type.?; | |
| 5679 | ||
| 5680 | fn buildSimplePanic(fg: *FuncGen, panic_cause_tag: PanicCauseTag) !void { | |
| 5681 | // TODO update this before merging the branch | |
| 5682 | _ = panic_cause_tag; | |
| 5683 | //const o = fg.ng.object; | |
| 5684 | //const zcu = o.pt.zcu; | |
| 5685 | //const ip = &zcu.intern_pool; | |
| 5686 | //const msg_nav_index = zcu.panic_messages[@intFromEnum(panic_id)].unwrap().?; | |
| 5687 | //const msg_nav = ip.getNav(msg_nav_index); | |
| 5688 | //const msg_len = Type.fromInterned(msg_nav.typeOf(ip)).childType(zcu).arrayLen(zcu); | |
| 5689 | //const msg_ptr = try o.lowerValue(msg_nav.status.resolved.val); | |
| 5690 | //const null_opt_addr_global = try fg.resolveNullOptUsize(); | |
| 5691 | //const target = zcu.getTarget(); | |
| 5692 | //const llvm_usize = try o.lowerType(Type.usize); | |
| 5693 | //// example: | |
| 5694 | //// call fastcc void @test2.panic( | |
| 5695 | //// ptr @builtin.panic_messages.integer_overflow__anon_987, ; msg.ptr | |
| 5696 | //// i64 16, ; msg.len | |
| 5697 | //// ptr null, ; stack trace | |
| 5698 | //// ptr @2, ; addr (null ?usize) | |
| 5699 | //// ) | |
| 5700 | //const panic_func = zcu.funcInfo(zcu.panic_func_index); | |
| 5701 | //const panic_nav = ip.getNav(panic_func.owner_nav); | |
| 5702 | //const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?; | |
| 5703 | //const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav); | |
| 5704 | //_ = try fg.wip.callIntrinsicAssumeCold(); | |
| 5705 | //_ = try fg.wip.call( | |
| 5706 | // .normal, | |
| 5707 | // toLlvmCallConv(fn_info.cc, target), | |
| 5708 | // .none, | |
| 5709 | // panic_global.typeOf(&o.builder), | |
| 5710 | // panic_global.toValue(&o.builder), | |
| 5711 | // &.{ | |
| 5712 | // msg_ptr.toValue(), | |
| 5713 | // try o.builder.intValue(llvm_usize, msg_len), | |
| 5714 | // try o.builder.nullValue(.ptr), | |
| 5715 | // null_opt_addr_global.toValue(), | |
| 5716 | // }, | |
| 5717 | // "", | |
| 5718 | //); | |
| 5719 | _ = try fg.wip.callIntrinsic(.normal, .none, .trap, &.{}, &.{}, ""); | |
| 5715 | 5720 | _ = try fg.wip.@"unreachable"(); |
| 5716 | 5721 | } |
| 5717 | 5722 |
src/crash_report.zig+7-4| ... | ... | @@ -212,7 +212,7 @@ fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopa |
| 212 | 212 | else => .not_supported, |
| 213 | 213 | }; |
| 214 | 214 | |
| 215 | PanicSwitch.dispatch(null, stack_ctx, error_msg); | |
| 215 | PanicSwitch.dispatch(null, stack_ctx, .{ .explicit_call = error_msg }); | |
| 216 | 216 | } |
| 217 | 217 | |
| 218 | 218 | const WindowsSegfaultMessage = union(enum) { |
| ... | ... | @@ -338,7 +338,7 @@ const PanicSwitch = struct { |
| 338 | 338 | // it's happening and print a message. |
| 339 | 339 | var panic_state: *volatile PanicState = &panic_state_raw; |
| 340 | 340 | if (panic_state.awaiting_dispatch) { |
| 341 | dispatch(null, .{ .current = .{ .ret_addr = null } }, "Panic while preparing callstack"); | |
| 341 | dispatch(null, .{ .current = .{ .ret_addr = null } }, .{ .explicit_call = "Panic while preparing callstack" }); | |
| 342 | 342 | } |
| 343 | 343 | panic_state.awaiting_dispatch = true; |
| 344 | 344 | } |
| ... | ... | @@ -518,6 +518,7 @@ const PanicSwitch = struct { |
| 518 | 518 | stack: StackContext, |
| 519 | 519 | panic_cause: std.builtin.PanicCause, |
| 520 | 520 | ) void { |
| 521 | var buffer: [1000]u8 = undefined; | |
| 521 | 522 | switch (state.recover_verbosity) { |
| 522 | 523 | .message_and_stack => { |
| 523 | 524 | // lower the verbosity, and restore it at the end if we don't panic. |
| ... | ... | @@ -525,7 +526,8 @@ const PanicSwitch = struct { |
| 525 | 526 | |
| 526 | 527 | const stderr = io.getStdErr().writer(); |
| 527 | 528 | stderr.writeAll("\nPanicked during a panic: ") catch {}; |
| 528 | stderr.writeAll(panic_cause) catch {}; | |
| 529 | const msg = buffer[0..std.debug.fmtPanicCause(&buffer, panic_cause)]; | |
| 530 | stderr.writeAll(msg) catch {}; | |
| 529 | 531 | stderr.writeAll("\nInner panic stack:\n") catch {}; |
| 530 | 532 | if (trace) |t| { |
| 531 | 533 | debug.dumpStackTrace(t.*); |
| ... | ... | @@ -539,7 +541,8 @@ const PanicSwitch = struct { |
| 539 | 541 | |
| 540 | 542 | const stderr = io.getStdErr().writer(); |
| 541 | 543 | stderr.writeAll("\nPanicked while dumping inner panic stack: ") catch {}; |
| 542 | stderr.writeAll(panic_cause) catch {}; | |
| 544 | const msg = buffer[0..std.debug.fmtPanicCause(&buffer, panic_cause)]; | |
| 545 | stderr.writeAll(msg) catch {}; | |
| 543 | 546 | stderr.writeAll("\n") catch {}; |
| 544 | 547 | |
| 545 | 548 | // If we succeed, restore all the way to dumping the stack. |