diff --git a/src/Sema.zig b/src/Sema.zig index 1b98ba3fe8..3d4844015c 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -5703,27 +5703,7 @@ fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air. } fn uavRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref { - return Air.internedToRef(try sema.refValue(val)); -} - -fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index { - const pt = sema.pt; - const ptr_ty = (try pt.ptrTypeSema(.{ - .child = pt.zcu.intern_pool.typeOf(val), - .flags = .{ - .alignment = .none, - .is_const = true, - .address_space = .generic, - }, - })).toIntern(); - return pt.intern(.{ .ptr = .{ - .ty = ptr_ty, - .base_addr = .{ .uav = .{ - .val = val, - .orig_ty = ptr_ty, - } }, - .byte_offset = 0, - } }); + return Air.internedToRef(try sema.pt.refValue(val)); } fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -17402,6 +17382,7 @@ fn analyzeArithmetic( if (block.wantSafety() and want_safety and scalar_tag == .int) { if (zcu.backendSupportsFeature(.safety_checked_instructions)) { + if (air_tag != air_tag_safe) try sema.preparePanicIntegerOverflow(block, src); return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs); } else { const maybe_op_ov: ?Air.Inst.Tag = switch (air_tag) { @@ -27706,6 +27687,24 @@ fn preparePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void { const panic_cause_ty = try pt.getBuiltinType("PanicCause"); try panic_cause_ty.resolveFields(pt); zcu.panic_cause_type = panic_cause_ty.toIntern(); + zcu.panic_cause_tag_type = panic_cause_ty.unionTagType(zcu).?.toIntern(); + } +} + +fn preparePanicIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc) !void { + const pt = sema.pt; + const zcu = pt.zcu; + try preparePanic(sema, block, src); + if (zcu.panic_cause_integer_overflow == .none) { + const union_val = try pt.unionValue( + Type.fromInterned(zcu.panic_cause_type), + try pt.enumValueFieldIndex( + Type.fromInterned(zcu.panic_cause_tag_type), + @intFromEnum(PanicCauseTag.integer_overflow), + ), + Value.void, + ); + zcu.panic_cause_integer_overflow = try pt.refValue(union_val.toIntern()); } } @@ -32669,7 +32668,7 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { return Value.fromInterned(try pt.intern(.{ .opt = .{ .ty = (try pt.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(), .val = if (opt_val) |val| (try pt.getCoerced( - Value.fromInterned(try sema.refValue(val.toIntern())), + Value.fromInterned(try pt.refValue(val.toIntern())), ptr_anyopaque_ty, )).toIntern() else .none, } })); diff --git a/src/Zcu.zig b/src/Zcu.zig index f5f433ed9c..34c074d3d4 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -214,6 +214,8 @@ free_type_references: std.ArrayListUnmanaged(u32) = .empty, panic_func_index: InternPool.Index = .none, null_stack_trace: InternPool.Index = .none, panic_cause_type: InternPool.Index = .none, +panic_cause_tag_type: InternPool.Index = .none, +panic_cause_integer_overflow: InternPool.Index = .none, generation: u32 = 0, diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index a0e90e60bd..6ba7e2b707 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -3656,6 +3656,25 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace namespace.generation = zcu.generation; } +pub fn refValue(pt: Zcu.PerThread, val: InternPool.Index) Zcu.SemaError!InternPool.Index { + const ptr_ty = (try pt.ptrTypeSema(.{ + .child = pt.zcu.intern_pool.typeOf(val), + .flags = .{ + .alignment = .none, + .is_const = true, + .address_space = .generic, + }, + })).toIntern(); + return pt.intern(.{ .ptr = .{ + .ty = ptr_ty, + .base_addr = .{ .uav = .{ + .val = val, + .orig_ty = ptr_ty, + } }, + .byte_offset = 0, + } }); +} + const Air = @import("../Air.zig"); const Allocator = std.mem.Allocator; const assert = std.debug.assert; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 78ac35e9eb..409ed742b4 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -5677,46 +5677,37 @@ pub const FuncGen = struct { 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, &.{}, &.{}, ""); + fn buildSimplePanic(fg: *FuncGen, panic_cause: InternPool.Index) !void { + const o = fg.ng.object; + const zcu = o.pt.zcu; + const ip = &zcu.intern_pool; + const cause_ptr = try o.lowerValue(panic_cause); + const null_opt_addr_global = try fg.resolveNullOptUsize(); + const target = zcu.getTarget(); + // example: + // call fastcc void @test2.panic( + // ptr @foo, ; panic_cause + // 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), + &.{ + cause_ptr.toValue(), + try o.builder.nullValue(.ptr), + null_opt_addr_global.toValue(), + }, + "", + ); _ = try fg.wip.@"unreachable"(); } @@ -8340,7 +8331,7 @@ pub const FuncGen = struct { _ = try fg.wip.brCond(overflow_bit, fail_block, ok_block, .none); fg.wip.cursor = .{ .block = fail_block }; - try fg.buildSimplePanic(.integer_overflow); + try fg.buildSimplePanic(zcu.panic_cause_integer_overflow); fg.wip.cursor = .{ .block = ok_block }; return fg.wip.extractValue(results, &.{0}, "");