Commit 9ccf8d3332

Andrew Kelley <andrew@ziglang.org>
2024-09-25 22:22:47
fixes for this branch
I had to bring back some of the old API so that I could compile the new compiler with an old compiler.
1 parent 4f8d244
Changed files (5)
lib/std/builtin.zig
@@ -761,18 +761,91 @@ pub const TestFn = struct {
     func: *const fn () anyerror!void,
 };
 
+const old_version = std.SemanticVersion.parse("0.14.0-dev.1659+4ceefca14") catch unreachable;
+const is_old = @import("builtin").zig_version.order(old_version) != .gt;
+
 /// This function type is used by the Zig language code generation and
 /// therefore must be kept in sync with the compiler implementation.
-pub const PanicFn = fn (PanicCause, ?*StackTrace, ?usize) noreturn;
+pub const PanicFn = if (is_old)
+    fn ([]const u8, ?*StackTrace, ?usize) noreturn
+else
+    fn (PanicCause, ?*StackTrace, ?usize) noreturn;
 
 /// The entry point for auto-generated calls by the compiler.
-pub const panic: PanicFn = if (@hasDecl(root, "panic"))
+pub const panic: PanicFn = if (is_old)
+    defaultPanicOld
+else if (@hasDecl(root, "panic"))
     root.panic
 else if (@hasDecl(root, "os") and @hasDecl(root.os, "panic"))
     root.os.panic
 else
     std.debug.defaultPanic;
 
+pub fn defaultPanicOld(
+    msg: []const u8,
+    trace: ?*const std.builtin.StackTrace,
+    first_trace_addr: ?usize,
+) noreturn {
+    @branchHint(.cold);
+    std.debug.print("old panic: {s}\n", .{msg});
+    _ = trace;
+    _ = first_trace_addr;
+    @trap();
+}
+
+pub fn panicSentinelMismatch(expected: anytype, actual: @TypeOf(expected)) noreturn {
+    @branchHint(.cold);
+    std.debug.panicExtra(null, @returnAddress(), "sentinel mismatch: expected {any}, found {any}", .{ expected, actual });
+}
+
+pub fn panicUnwrapError(st: ?*StackTrace, err: anyerror) noreturn {
+    @branchHint(.cold);
+    std.debug.panicExtra(st, @returnAddress(), "attempt to unwrap error: {s}", .{@errorName(err)});
+}
+
+pub fn panicOutOfBounds(index: usize, len: usize) noreturn {
+    @branchHint(.cold);
+    std.debug.panicExtra(null, @returnAddress(), "index out of bounds: index {d}, len {d}", .{ index, len });
+}
+
+pub fn panicStartGreaterThanEnd(start: usize, end: usize) noreturn {
+    @branchHint(.cold);
+    std.debug.panicExtra(null, @returnAddress(), "start index {d} is larger than end index {d}", .{ start, end });
+}
+
+pub fn panicInactiveUnionField(active: anytype, wanted: @TypeOf(active)) noreturn {
+    @branchHint(.cold);
+    std.debug.panicExtra(null, @returnAddress(), "access of union field '{s}' while field '{s}' is active", .{ @tagName(wanted), @tagName(active) });
+}
+
+pub const panic_messages = struct {
+    pub const unreach = "reached unreachable code";
+    pub const unwrap_null = "attempt to use null value";
+    pub const cast_to_null = "cast causes pointer to be null";
+    pub const incorrect_alignment = "incorrect alignment";
+    pub const invalid_error_code = "invalid error code";
+    pub const cast_truncated_data = "integer cast truncated bits";
+    pub const negative_to_unsigned = "attempt to cast negative value to unsigned integer";
+    pub const integer_overflow = "integer overflow";
+    pub const shl_overflow = "left shift overflowed bits";
+    pub const shr_overflow = "right shift overflowed bits";
+    pub const divide_by_zero = "division by zero";
+    pub const exact_division_remainder = "exact division produced remainder";
+    pub const inactive_union_field = "access of inactive union field";
+    pub const integer_part_out_of_bounds = "integer part of floating point value out of bounds";
+    pub const corrupt_switch = "switch on corrupt value";
+    pub const shift_rhs_too_big = "shift amount is greater than the type size";
+    pub const invalid_enum_value = "invalid enum value";
+    pub const sentinel_mismatch = "sentinel mismatch";
+    pub const unwrap_error = "attempt to unwrap error";
+    pub const index_out_of_bounds = "index out of bounds";
+    pub const start_index_greater_than_end = "start index is larger than end index";
+    pub const for_len_mismatch = "for loop over objects with non-equal lengths";
+    pub const memcpy_len_mismatch = "@memcpy arguments have non-equal lengths";
+    pub const memcpy_alias = "@memcpy arguments alias";
+    pub const noreturn_returned = "'noreturn' function returned";
+};
+
 /// This data structure is used by the Zig language code generation and
 /// therefore must be kept in sync with the compiler implementation.
 pub const PanicCause = union(enum) {
lib/std/debug.zig
@@ -437,7 +437,7 @@ pub fn panicExtra(
             break :blk &buf;
         },
     };
-    std.builtin.panic(msg, trace, ret_addr);
+    std.builtin.panic(.{ .explicit_call = msg }, trace, ret_addr);
 }
 
 /// Non-zero whenever the program triggered a panic.
@@ -487,18 +487,6 @@ pub fn defaultPanic(
         .freestanding => {
             @trap();
         },
-        .wasi => {
-            // TODO: before merging my branch, unify this logic with the main panic logic
-            var buffer: [1000]u8 = undefined;
-            var i: usize = 0;
-            i += fmtPanicCause(buffer[i..], cause);
-            buffer[i] = '\n';
-            i += 1;
-            const msg = buffer[0..i];
-            lockStdErr();
-            io.getStdErr().writeAll(msg) catch {};
-            @trap();
-        },
         .uefi => {
             const uefi = std.os.uefi;
 
@@ -571,7 +559,7 @@ pub fn defaultPanic(
                     i += fmtInt10(buffer[i..], std.Thread.getCurrentId());
                     i += fmtBuf(buffer[i..], " panic: ");
                 }
-                i += fmtPanicCause(&buffer, cause);
+                i += fmtPanicCause(buffer[i..], cause);
                 buffer[i] = '\n';
                 i += 1;
                 const msg = buffer[0..i];
@@ -672,7 +660,7 @@ fn fmtInt10(out_buf: []u8, integer_value: usize) usize {
 
     while (true) {
         i -= 1;
-        tmp_buf[i] = '0' + (a % 10);
+        tmp_buf[i] = '0' + @as(u8, @intCast(a % 10));
         a /= 10;
         if (a == 0) break;
     }
src/codegen/llvm.zig
@@ -3848,13 +3848,13 @@ pub const Object = struct {
 
             .undef => unreachable, // handled above
             .simple_value => |simple_value| switch (simple_value) {
-                .undefined,
-                .void,
-                .null,
-                .empty_struct,
-                .@"unreachable",
-                .generic_poison,
-                => unreachable, // non-runtime values
+                .undefined => unreachable, // non-runtime value
+                .void => unreachable, // non-runtime value
+                .null => unreachable, // non-runtime value
+                .empty_struct => unreachable, // non-runtime value
+                .@"unreachable" => unreachable, // non-runtime value
+                .generic_poison => unreachable, // non-runtime value
+
                 .false => .false,
                 .true => .true,
             },
@@ -5675,43 +5675,48 @@ pub const FuncGen = struct {
         }
     }
 
-    fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.PanicId) !void {
-        const o = fg.ng.object;
-        const zcu = o.pt.zcu;
-        const ip = &zcu.intern_pool;
-        const msg_nav_index = zcu.panic_messages[@intFromEnum(panic_id)].unwrap().?;
-        const msg_nav = ip.getNav(msg_nav_index);
-        const msg_len = Type.fromInterned(msg_nav.typeOf(ip)).childType(zcu).arrayLen(zcu);
-        const msg_ptr = try o.lowerValue(msg_nav.status.resolved.val);
-        const null_opt_addr_global = try fg.resolveNullOptUsize();
-        const target = zcu.getTarget();
-        const llvm_usize = try o.lowerType(Type.usize);
-        // example:
-        // call fastcc void @test2.panic(
-        //   ptr @builtin.panic_messages.integer_overflow__anon_987, ; msg.ptr
-        //   i64 16,                                                 ; msg.len
-        //   ptr null,                                               ; stack trace
-        //   ptr @2,                                                 ; addr (null ?usize)
-        // )
-        const panic_func = zcu.funcInfo(zcu.panic_func_index);
-        const panic_nav = ip.getNav(panic_func.owner_nav);
-        const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?;
-        const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav);
-        _ = try fg.wip.callIntrinsicAssumeCold();
-        _ = try fg.wip.call(
-            .normal,
-            toLlvmCallConv(fn_info.cc, target),
-            .none,
-            panic_global.typeOf(&o.builder),
-            panic_global.toValue(&o.builder),
-            &.{
-                msg_ptr.toValue(),
-                try o.builder.intValue(llvm_usize, msg_len),
-                try o.builder.nullValue(.ptr),
-                null_opt_addr_global.toValue(),
-            },
-            "",
-        );
+    const PanicCauseTag = @typeInfo(std.builtin.PanicCause).@"union".tag_type.?;
+
+    fn buildSimplePanic(fg: *FuncGen, panic_cause_tag: PanicCauseTag) !void {
+        // TODO update this before merging the branch
+        _ = panic_cause_tag;
+        //const o = fg.ng.object;
+        //const zcu = o.pt.zcu;
+        //const ip = &zcu.intern_pool;
+        //const msg_nav_index = zcu.panic_messages[@intFromEnum(panic_id)].unwrap().?;
+        //const msg_nav = ip.getNav(msg_nav_index);
+        //const msg_len = Type.fromInterned(msg_nav.typeOf(ip)).childType(zcu).arrayLen(zcu);
+        //const msg_ptr = try o.lowerValue(msg_nav.status.resolved.val);
+        //const null_opt_addr_global = try fg.resolveNullOptUsize();
+        //const target = zcu.getTarget();
+        //const llvm_usize = try o.lowerType(Type.usize);
+        //// example:
+        //// call fastcc void @test2.panic(
+        ////   ptr @builtin.panic_messages.integer_overflow__anon_987, ; msg.ptr
+        ////   i64 16,                                                 ; msg.len
+        ////   ptr null,                                               ; stack trace
+        ////   ptr @2,                                                 ; addr (null ?usize)
+        //// )
+        //const panic_func = zcu.funcInfo(zcu.panic_func_index);
+        //const panic_nav = ip.getNav(panic_func.owner_nav);
+        //const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?;
+        //const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav);
+        //_ = try fg.wip.callIntrinsicAssumeCold();
+        //_ = try fg.wip.call(
+        //    .normal,
+        //    toLlvmCallConv(fn_info.cc, target),
+        //    .none,
+        //    panic_global.typeOf(&o.builder),
+        //    panic_global.toValue(&o.builder),
+        //    &.{
+        //        msg_ptr.toValue(),
+        //        try o.builder.intValue(llvm_usize, msg_len),
+        //        try o.builder.nullValue(.ptr),
+        //        null_opt_addr_global.toValue(),
+        //    },
+        //    "",
+        //);
+        _ = try fg.wip.callIntrinsic(.normal, .none, .trap, &.{}, &.{}, "");
         _ = try fg.wip.@"unreachable"();
     }
 
src/crash_report.zig
@@ -212,7 +212,7 @@ fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopa
         else => .not_supported,
     };
 
-    PanicSwitch.dispatch(null, stack_ctx, error_msg);
+    PanicSwitch.dispatch(null, stack_ctx, .{ .explicit_call = error_msg });
 }
 
 const WindowsSegfaultMessage = union(enum) {
@@ -338,7 +338,7 @@ const PanicSwitch = struct {
         // it's happening and print a message.
         var panic_state: *volatile PanicState = &panic_state_raw;
         if (panic_state.awaiting_dispatch) {
-            dispatch(null, .{ .current = .{ .ret_addr = null } }, "Panic while preparing callstack");
+            dispatch(null, .{ .current = .{ .ret_addr = null } }, .{ .explicit_call = "Panic while preparing callstack" });
         }
         panic_state.awaiting_dispatch = true;
     }
@@ -518,6 +518,7 @@ const PanicSwitch = struct {
         stack: StackContext,
         panic_cause: std.builtin.PanicCause,
     ) void {
+        var buffer: [1000]u8 = undefined;
         switch (state.recover_verbosity) {
             .message_and_stack => {
                 // lower the verbosity, and restore it at the end if we don't panic.
@@ -525,7 +526,8 @@ const PanicSwitch = struct {
 
                 const stderr = io.getStdErr().writer();
                 stderr.writeAll("\nPanicked during a panic: ") catch {};
-                stderr.writeAll(panic_cause) catch {};
+                const msg = buffer[0..std.debug.fmtPanicCause(&buffer, panic_cause)];
+                stderr.writeAll(msg) catch {};
                 stderr.writeAll("\nInner panic stack:\n") catch {};
                 if (trace) |t| {
                     debug.dumpStackTrace(t.*);
@@ -539,7 +541,8 @@ const PanicSwitch = struct {
 
                 const stderr = io.getStdErr().writer();
                 stderr.writeAll("\nPanicked while dumping inner panic stack: ") catch {};
-                stderr.writeAll(panic_cause) catch {};
+                const msg = buffer[0..std.debug.fmtPanicCause(&buffer, panic_cause)];
+                stderr.writeAll(msg) catch {};
                 stderr.writeAll("\n") catch {};
 
                 // If we succeed, restore all the way to dumping the stack.
src/Sema.zig
@@ -2566,7 +2566,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
         std.debug.print("compile error during Sema:\n", .{});
         var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory");
         error_bundle.renderToStdErr(.{ .ttyconf = .no_color });
-        crash_report.compilerPanic("unexpected compile error occurred", null, null);
+        crash_report.compilerPanic(.{ .explicit_call = "unexpected compile error occurred" }, null, null);
     }
 
     if (block) |start_block| {
@@ -7334,17 +7334,21 @@ fn callPanic(
     call_operation: CallOperation,
 ) !void {
     const pt = sema.pt;
-    if (!pt.zcu.backendSupportsFeature(.panic_fn)) {
+    const zcu = pt.zcu;
+    if (!zcu.backendSupportsFeature(.panic_fn)) {
         _ = try block.addNoOp(.trap);
         return;
     }
     const panic_cause_ty = try pt.getBuiltinType("PanicCause");
-    const panic_cause = try block.addUnionInit(panic_cause_ty, @intFromEnum(tag), payload);
+    const panic_cause = if (payload == .void_value)
+        try initUnionFromEnumTag(pt, panic_cause_ty, panic_cause_ty.unionTagType(zcu).?, @intFromEnum(tag))
+    else
+        try block.addUnionInit(panic_cause_ty, @intFromEnum(tag), payload);
     const panic_fn = try pt.getBuiltin("panic");
     const err_return_trace = try sema.getErrorReturnTrace(block);
     const opt_usize_ty = try pt.optionalType(.usize_type);
     const null_usize = try pt.nullValue(opt_usize_ty);
-    const args: [3]Air.Inst.Ref = .{ panic_cause, err_return_trace, Air.internedToRef(null_usize) };
+    const args: [3]Air.Inst.Ref = .{ panic_cause, err_return_trace, Air.internedToRef(null_usize.toIntern()) };
     try sema.callBuiltin(block, call_src, panic_fn, .auto, &args, call_operation);
 }
 
@@ -18326,11 +18330,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
         .undefined,
         .null,
         .enum_literal,
-        => |type_info_tag| return Air.internedToRef((try pt.internUnion(.{
-            .ty = type_info_ty.toIntern(),
-            .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(type_info_tag))).toIntern(),
-            .val = .void_value,
-        }))),
+        => |type_info_tag| return initUnionFromEnumTag(pt, type_info_ty, type_info_tag_ty, @intFromEnum(type_info_tag)),
         .@"fn" => {
             const fn_info_ty = try getInnerType(sema, block, src, type_info_ty, "Fn");
             const param_info_ty = try getInnerType(sema, block, src, fn_info_ty, "Param");
@@ -28009,7 +28009,7 @@ fn addSafetyCheckSentinelMismatch(
             assert(std.mem.eql(u8, fields[1].name, "found"));
             assert(fields.len == 2);
         }
-        const panic_cause_payload = &fail_block.addAggregateInit(mm_ty, &.{ expected_sentinel, actual_sentinel });
+        const panic_cause_payload = try fail_block.addAggregateInit(mm_ty, &.{ expected_sentinel, actual_sentinel });
         try callPanic(sema, &fail_block, src, .sentinel_mismatch_usize, panic_cause_payload, .@"safety check");
     } else {
         try callPanic(sema, &fail_block, src, .sentinel_mismatch_other, .void_value, .@"safety check");
@@ -38997,3 +38997,11 @@ fn getInnerType(
     try sema.ensureNavResolved(src, nav);
     return Type.fromInterned(ip.getNav(nav).status.resolved.val);
 }
+
+fn initUnionFromEnumTag(pt: Zcu.PerThread, union_ty: Type, union_tag_ty: Type, field_index: u32) !Air.Inst.Ref {
+    return Air.internedToRef((try pt.internUnion(.{
+        .ty = union_ty.toIntern(),
+        .tag = (try pt.enumValueFieldIndex(union_tag_ty, field_index)).toIntern(),
+        .val = .void_value,
+    })));
+}