| ... | @@ -667,9 +667,9 @@ pub const Block = struct { | ... | @@ -667,9 +667,9 @@ pub const Block = struct { |
| 667 | return result_index; | 667 | return result_index; |
| 668 | } | 668 | } |
| 669 | | 669 | |
| 670 | fn addUnreachable(block: *Block, src: LazySrcLoc, safety_check: bool) !void { | 670 | fn addUnreachable(block: *Block, safety_check: bool) !void { |
| 671 | if (safety_check and block.wantSafety()) { | 671 | if (safety_check and block.wantSafety()) { |
| 672 | _ = try block.sema.safetyPanic(block, src, .unreach); | 672 | try block.sema.safetyPanic(block, .unreach); |
| 673 | } else { | 673 | } else { |
| 674 | _ = try block.addNoOp(.unreach); | 674 | _ = try block.addNoOp(.unreach); |
| 675 | } | 675 | } |
| ... | @@ -5003,7 +5003,8 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bo | ... | @@ -5003,7 +5003,8 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bo |
| 5003 | if (block.is_comptime or force_comptime) { | 5003 | if (block.is_comptime or force_comptime) { |
| 5004 | return sema.fail(block, src, "encountered @panic at comptime", .{}); | 5004 | return sema.fail(block, src, "encountered @panic at comptime", .{}); |
| 5005 | } | 5005 | } |
| 5006 | return sema.panicWithMsg(block, src, msg_inst); | 5006 | try sema.panicWithMsg(block, src, msg_inst); |
| | 5007 | return always_noreturn; |
| 5007 | } | 5008 | } |
| 5008 | | 5009 | |
| 5009 | fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5010 | fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -7962,7 +7963,7 @@ fn analyzeErrUnionPayload( | ... | @@ -7962,7 +7963,7 @@ fn analyzeErrUnionPayload( |
| 7962 | if (safety_check and block.wantSafety() and | 7963 | if (safety_check and block.wantSafety() and |
| 7963 | !err_union_ty.errorUnionSet().errorSetIsEmpty()) | 7964 | !err_union_ty.errorUnionSet().errorSetIsEmpty()) |
| 7964 | { | 7965 | { |
| 7965 | try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err); | 7966 | try sema.panicUnwrapError(block, operand, .unwrap_errunion_err, .is_non_err); |
| 7966 | } | 7967 | } |
| 7967 | | 7968 | |
| 7968 | return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand); | 7969 | return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand); |
| ... | @@ -8047,7 +8048,7 @@ fn analyzeErrUnionPayloadPtr( | ... | @@ -8047,7 +8048,7 @@ fn analyzeErrUnionPayloadPtr( |
| 8047 | if (safety_check and block.wantSafety() and | 8048 | if (safety_check and block.wantSafety() and |
| 8048 | !err_union_ty.errorUnionSet().errorSetIsEmpty()) | 8049 | !err_union_ty.errorUnionSet().errorSetIsEmpty()) |
| 8049 | { | 8050 | { |
| 8050 | try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr); | 8051 | try sema.panicUnwrapError(block, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr); |
| 8051 | } | 8052 | } |
| 8052 | | 8053 | |
| 8053 | const air_tag: Air.Inst.Tag = if (initializing) | 8054 | const air_tag: Air.Inst.Tag = if (initializing) |
| ... | @@ -9542,7 +9543,7 @@ fn zirSwitchCapture( | ... | @@ -9542,7 +9543,7 @@ fn zirSwitchCapture( |
| 9542 | .ErrorSet => if (block.switch_else_err_ty) |some| { | 9543 | .ErrorSet => if (block.switch_else_err_ty) |some| { |
| 9543 | return sema.bitCast(block, some, operand, operand_src); | 9544 | return sema.bitCast(block, some, operand, operand_src); |
| 9544 | } else { | 9545 | } else { |
| 9545 | try block.addUnreachable(operand_src, false); | 9546 | try block.addUnreachable(false); |
| 9546 | return Air.Inst.Ref.unreachable_value; | 9547 | return Air.Inst.Ref.unreachable_value; |
| 9547 | }, | 9548 | }, |
| 9548 | else => return operand, | 9549 | else => return operand, |
| ... | @@ -10975,7 +10976,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10975,7 +10976,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10975 | // that it is unreachable. | 10976 | // that it is unreachable. |
| 10976 | if (case_block.wantSafety()) { | 10977 | if (case_block.wantSafety()) { |
| 10977 | try sema.zirDbgStmt(&case_block, cond_dbg_node_index); | 10978 | try sema.zirDbgStmt(&case_block, cond_dbg_node_index); |
| 10978 | _ = try sema.safetyPanic(&case_block, src, .corrupt_switch); | 10979 | try sema.safetyPanic(&case_block, .corrupt_switch); |
| 10979 | } else { | 10980 | } else { |
| 10980 | _ = try case_block.addNoOp(.unreach); | 10981 | _ = try case_block.addNoOp(.unreach); |
| 10981 | } | 10982 | } |
| ... | @@ -11304,6 +11305,11 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op | ... | @@ -11304,6 +11305,11 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op |
| 11304 | const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable"; | 11305 | const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable"; |
| 11305 | const src = inst_data.src(); | 11306 | const src = inst_data.src(); |
| 11306 | | 11307 | |
| | 11308 | if (!sema.mod.comp.formatted_panics) { |
| | 11309 | try sema.safetyPanic(block, .unwrap_error); |
| | 11310 | return true; |
| | 11311 | } |
| | 11312 | |
| 11307 | const panic_fn = try sema.getBuiltin("panicUnwrapError"); | 11313 | const panic_fn = try sema.getBuiltin("panicUnwrapError"); |
| 11308 | const err_return_trace = try sema.getErrorReturnTrace(block); | 11314 | const err_return_trace = try sema.getErrorReturnTrace(block); |
| 11309 | const args: [2]Air.Inst.Ref = .{ err_return_trace, operand }; | 11315 | const args: [2]Air.Inst.Ref = .{ err_return_trace, operand }; |
| ... | @@ -16513,7 +16519,7 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -16513,7 +16519,7 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 16513 | return sema.fail(block, src, "reached unreachable code", .{}); | 16519 | return sema.fail(block, src, "reached unreachable code", .{}); |
| 16514 | } | 16520 | } |
| 16515 | // TODO Add compile error for @optimizeFor occurring too late in a scope. | 16521 | // TODO Add compile error for @optimizeFor occurring too late in a scope. |
| 16516 | try block.addUnreachable(src, true); | 16522 | try block.addUnreachable(true); |
| 16517 | return always_noreturn; | 16523 | return always_noreturn; |
| 16518 | } | 16524 | } |
| 16519 | | 16525 | |
| ... | @@ -22128,6 +22134,10 @@ pub const PanicId = enum { | ... | @@ -22128,6 +22134,10 @@ pub const PanicId = enum { |
| 22128 | corrupt_switch, | 22134 | corrupt_switch, |
| 22129 | shift_rhs_too_big, | 22135 | shift_rhs_too_big, |
| 22130 | invalid_enum_value, | 22136 | invalid_enum_value, |
| | 22137 | sentinel_mismatch, |
| | 22138 | unwrap_error, |
| | 22139 | index_out_of_bounds, |
| | 22140 | start_index_greater_than_end, |
| 22131 | }; | 22141 | }; |
| 22132 | | 22142 | |
| 22133 | fn addSafetyCheck( | 22143 | fn addSafetyCheck( |
| ... | @@ -22152,12 +22162,7 @@ fn addSafetyCheck( | ... | @@ -22152,12 +22162,7 @@ fn addSafetyCheck( |
| 22152 | | 22162 | |
| 22153 | defer fail_block.instructions.deinit(gpa); | 22163 | defer fail_block.instructions.deinit(gpa); |
| 22154 | | 22164 | |
| 22155 | // This function doesn't actually need a src location but if | 22165 | try sema.safetyPanic(&fail_block, panic_id); |
| 22156 | // the panic function interface ever changes passing `.unneeded` here | | |
| 22157 | // will cause confusing panics. | | |
| 22158 | const src = sema.src; | | |
| 22159 | _ = try sema.safetyPanic(&fail_block, src, panic_id); | | |
| 22160 | | | |
| 22161 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); | 22166 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| 22162 | } | 22167 | } |
| 22163 | | 22168 | |
| ... | @@ -22221,7 +22226,7 @@ fn panicWithMsg( | ... | @@ -22221,7 +22226,7 @@ fn panicWithMsg( |
| 22221 | block: *Block, | 22226 | block: *Block, |
| 22222 | src: LazySrcLoc, | 22227 | src: LazySrcLoc, |
| 22223 | msg_inst: Air.Inst.Ref, | 22228 | msg_inst: Air.Inst.Ref, |
| 22224 | ) !Zir.Inst.Index { | 22229 | ) !void { |
| 22225 | const mod = sema.mod; | 22230 | const mod = sema.mod; |
| 22226 | const arena = sema.arena; | 22231 | const arena = sema.arena; |
| 22227 | | 22232 | |
| ... | @@ -22232,7 +22237,7 @@ fn panicWithMsg( | ... | @@ -22232,7 +22237,7 @@ fn panicWithMsg( |
| 22232 | // TODO implement this feature in all the backends and then delete this branch | 22237 | // TODO implement this feature in all the backends and then delete this branch |
| 22233 | _ = try block.addNoOp(.breakpoint); | 22238 | _ = try block.addNoOp(.breakpoint); |
| 22234 | _ = try block.addNoOp(.unreach); | 22239 | _ = try block.addNoOp(.unreach); |
| 22235 | return always_noreturn; | 22240 | return; |
| 22236 | } | 22241 | } |
| 22237 | const panic_fn = try sema.getBuiltin("panic"); | 22242 | const panic_fn = try sema.getBuiltin("panic"); |
| 22238 | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); | 22243 | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| ... | @@ -22248,19 +22253,20 @@ fn panicWithMsg( | ... | @@ -22248,19 +22253,20 @@ fn panicWithMsg( |
| 22248 | ); | 22253 | ); |
| 22249 | const args: [3]Air.Inst.Ref = .{ msg_inst, null_stack_trace, .null_value }; | 22254 | const args: [3]Air.Inst.Ref = .{ msg_inst, null_stack_trace, .null_value }; |
| 22250 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null); | 22255 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null); |
| 22251 | return always_noreturn; | | |
| 22252 | } | 22256 | } |
| 22253 | | 22257 | |
| 22254 | fn panicUnwrapError( | 22258 | fn panicUnwrapError( |
| 22255 | sema: *Sema, | 22259 | sema: *Sema, |
| 22256 | parent_block: *Block, | 22260 | parent_block: *Block, |
| 22257 | src: LazySrcLoc, | | |
| 22258 | operand: Air.Inst.Ref, | 22261 | operand: Air.Inst.Ref, |
| 22259 | unwrap_err_tag: Air.Inst.Tag, | 22262 | unwrap_err_tag: Air.Inst.Tag, |
| 22260 | is_non_err_tag: Air.Inst.Tag, | 22263 | is_non_err_tag: Air.Inst.Tag, |
| 22261 | ) !void { | 22264 | ) !void { |
| 22262 | assert(!parent_block.is_comptime); | 22265 | assert(!parent_block.is_comptime); |
| 22263 | const ok = try parent_block.addUnOp(is_non_err_tag, operand); | 22266 | const ok = try parent_block.addUnOp(is_non_err_tag, operand); |
| | 22267 | if (!sema.mod.comp.formatted_panics) { |
| | 22268 | return sema.addSafetyCheck(parent_block, ok, .unwrap_error); |
| | 22269 | } |
| 22264 | const gpa = sema.gpa; | 22270 | const gpa = sema.gpa; |
| 22265 | | 22271 | |
| 22266 | var fail_block: Block = .{ | 22272 | var fail_block: Block = .{ |
| ... | @@ -22289,7 +22295,7 @@ fn panicUnwrapError( | ... | @@ -22289,7 +22295,7 @@ fn panicUnwrapError( |
| 22289 | const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand); | 22295 | const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand); |
| 22290 | const err_return_trace = try sema.getErrorReturnTrace(&fail_block); | 22296 | const err_return_trace = try sema.getErrorReturnTrace(&fail_block); |
| 22291 | const args: [2]Air.Inst.Ref = .{ err_return_trace, err }; | 22297 | const args: [2]Air.Inst.Ref = .{ err_return_trace, err }; |
| 22292 | _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null); | 22298 | _ = try sema.analyzeCall(&fail_block, panic_fn, sema.src, sema.src, .auto, false, &args, null); |
| 22293 | } | 22299 | } |
| 22294 | } | 22300 | } |
| 22295 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); | 22301 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| ... | @@ -22304,7 +22310,10 @@ fn panicIndexOutOfBounds( | ... | @@ -22304,7 +22310,10 @@ fn panicIndexOutOfBounds( |
| 22304 | ) !void { | 22310 | ) !void { |
| 22305 | assert(!parent_block.is_comptime); | 22311 | assert(!parent_block.is_comptime); |
| 22306 | const ok = try parent_block.addBinOp(cmp_op, index, len); | 22312 | const ok = try parent_block.addBinOp(cmp_op, index, len); |
| 22307 | try sema.safetyPanicFormatted(parent_block, ok, "panicOutOfBounds", &.{ index, len }); | 22313 | if (!sema.mod.comp.formatted_panics) { |
| | 22314 | return sema.addSafetyCheck(parent_block, ok, .index_out_of_bounds); |
| | 22315 | } |
| | 22316 | try sema.safetyCheckFormatted(parent_block, ok, "panicOutOfBounds", &.{ index, len }); |
| 22308 | } | 22317 | } |
| 22309 | | 22318 | |
| 22310 | fn panicStartLargerThanEnd( | 22319 | fn panicStartLargerThanEnd( |
| ... | @@ -22315,7 +22324,10 @@ fn panicStartLargerThanEnd( | ... | @@ -22315,7 +22324,10 @@ fn panicStartLargerThanEnd( |
| 22315 | ) !void { | 22324 | ) !void { |
| 22316 | assert(!parent_block.is_comptime); | 22325 | assert(!parent_block.is_comptime); |
| 22317 | const ok = try parent_block.addBinOp(.cmp_lte, start, end); | 22326 | const ok = try parent_block.addBinOp(.cmp_lte, start, end); |
| 22318 | try sema.safetyPanicFormatted(parent_block, ok, "panicStartGreaterThanEnd", &.{ start, end }); | 22327 | if (!sema.mod.comp.formatted_panics) { |
| | 22328 | return sema.addSafetyCheck(parent_block, ok, .start_index_greater_than_end); |
| | 22329 | } |
| | 22330 | try sema.safetyCheckFormatted(parent_block, ok, "panicStartGreaterThanEnd", &.{ start, end }); |
| 22319 | } | 22331 | } |
| 22320 | | 22332 | |
| 22321 | fn panicInactiveUnionField( | 22333 | fn panicInactiveUnionField( |
| ... | @@ -22326,7 +22338,10 @@ fn panicInactiveUnionField( | ... | @@ -22326,7 +22338,10 @@ fn panicInactiveUnionField( |
| 22326 | ) !void { | 22338 | ) !void { |
| 22327 | assert(!parent_block.is_comptime); | 22339 | assert(!parent_block.is_comptime); |
| 22328 | const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag); | 22340 | const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag); |
| 22329 | try sema.safetyPanicFormatted(parent_block, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag }); | 22341 | if (!sema.mod.comp.formatted_panics) { |
| | 22342 | return sema.addSafetyCheck(parent_block, ok, .inactive_union_field); |
| | 22343 | } |
| | 22344 | try sema.safetyCheckFormatted(parent_block, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag }); |
| 22330 | } | 22345 | } |
| 22331 | | 22346 | |
| 22332 | fn panicSentinelMismatch( | 22347 | fn panicSentinelMismatch( |
| ... | @@ -22369,16 +22384,20 @@ fn panicSentinelMismatch( | ... | @@ -22369,16 +22384,20 @@ fn panicSentinelMismatch( |
| 22369 | return; | 22384 | return; |
| 22370 | }; | 22385 | }; |
| 22371 | | 22386 | |
| 22372 | try sema.safetyPanicFormatted(parent_block, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel }); | 22387 | if (!sema.mod.comp.formatted_panics) { |
| | 22388 | return sema.addSafetyCheck(parent_block, ok, .sentinel_mismatch); |
| | 22389 | } |
| | 22390 | try sema.safetyCheckFormatted(parent_block, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel }); |
| 22373 | } | 22391 | } |
| 22374 | | 22392 | |
| 22375 | fn safetyPanicFormatted( | 22393 | fn safetyCheckFormatted( |
| 22376 | sema: *Sema, | 22394 | sema: *Sema, |
| 22377 | parent_block: *Block, | 22395 | parent_block: *Block, |
| 22378 | ok: Air.Inst.Ref, | 22396 | ok: Air.Inst.Ref, |
| 22379 | func: []const u8, | 22397 | func: []const u8, |
| 22380 | args: []const Air.Inst.Ref, | 22398 | args: []const Air.Inst.Ref, |
| 22381 | ) CompileError!void { | 22399 | ) CompileError!void { |
| | 22400 | assert(sema.mod.comp.formatted_panics); |
| 22382 | const gpa = sema.gpa; | 22401 | const gpa = sema.gpa; |
| 22383 | | 22402 | |
| 22384 | var fail_block: Block = .{ | 22403 | var fail_block: Block = .{ |
| ... | @@ -22413,19 +22432,18 @@ fn safetyPanicFormatted( | ... | @@ -22413,19 +22432,18 @@ fn safetyPanicFormatted( |
| 22413 | fn safetyPanic( | 22432 | fn safetyPanic( |
| 22414 | sema: *Sema, | 22433 | sema: *Sema, |
| 22415 | block: *Block, | 22434 | block: *Block, |
| 22416 | src: LazySrcLoc, | | |
| 22417 | panic_id: PanicId, | 22435 | panic_id: PanicId, |
| 22418 | ) CompileError!Zir.Inst.Index { | 22436 | ) CompileError!void { |
| 22419 | const panic_messages_ty = try sema.getBuiltinType("panic_messages"); | 22437 | const panic_messages_ty = try sema.getBuiltinType("panic_messages"); |
| 22420 | const msg_decl_index = (try sema.namespaceLookup( | 22438 | const msg_decl_index = (try sema.namespaceLookup( |
| 22421 | block, | 22439 | block, |
| 22422 | src, | 22440 | sema.src, |
| 22423 | panic_messages_ty.getNamespace().?, | 22441 | panic_messages_ty.getNamespace().?, |
| 22424 | @tagName(panic_id), | 22442 | @tagName(panic_id), |
| 22425 | )).?; | 22443 | )).?; |
| 22426 | | 22444 | |
| 22427 | const msg_inst = try sema.analyzeDeclVal(block, src, msg_decl_index); | 22445 | const msg_inst = try sema.analyzeDeclVal(block, sema.src, msg_decl_index); |
| 22428 | return sema.panicWithMsg(block, src, msg_inst); | 22446 | try sema.panicWithMsg(block, sema.src, msg_inst); |
| 22429 | } | 22447 | } |
| 22430 | | 22448 | |
| 22431 | fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void { | 22449 | fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void { |