| ... | ... | @@ -7080,15 +7080,38 @@ fn analyzeCall( |
| 7080 | 7080 | } }, |
| 7081 | 7081 | }); |
| 7082 | 7082 | sema.appendRefsAssumeCapacity(args); |
| 7083 | |
| 7084 | if (call_tag == .call_always_tail) { |
| 7085 | if (ensure_result_used) { |
| 7086 | try sema.ensureResultUsed(block, sema.typeOf(func_inst), call_src); |
| 7087 | } |
| 7088 | return sema.handleTailCall(block, call_src, func_ty, func_inst); |
| 7089 | } else if (block.wantSafety() and func_ty_info.return_type.isNoReturn()) { |
| 7090 | // Function pointers and extern functions aren't guaranteed to |
| 7091 | // actually be noreturn so we add a safety check for them. |
| 7092 | check: { |
| 7093 | var func_val = (try sema.resolveMaybeUndefVal(func)) orelse break :check; |
| 7094 | switch (func_val.tag()) { |
| 7095 | .function, .decl_ref => { |
| 7096 | _ = try block.addNoOp(.unreach); |
| 7097 | return Air.Inst.Ref.unreachable_value; |
| 7098 | }, |
| 7099 | else => break :check, |
| 7100 | } |
| 7101 | } |
| 7102 | |
| 7103 | try sema.safetyPanic(block, .noreturn_returned); |
| 7104 | return Air.Inst.Ref.unreachable_value; |
| 7105 | } else if (func_ty_info.return_type.isNoReturn()) { |
| 7106 | _ = try block.addNoOp(.unreach); |
| 7107 | return Air.Inst.Ref.unreachable_value; |
| 7108 | } |
| 7083 | 7109 | break :res func_inst; |
| 7084 | 7110 | }; |
| 7085 | 7111 | |
| 7086 | 7112 | if (ensure_result_used) { |
| 7087 | 7113 | try sema.ensureResultUsed(block, sema.typeOf(result), call_src); |
| 7088 | 7114 | } |
| 7089 | | if (call_tag == .call_always_tail) { |
| 7090 | | return sema.handleTailCall(block, call_src, func_ty, result); |
| 7091 | | } |
| 7092 | 7115 | return result; |
| 7093 | 7116 | } |
| 7094 | 7117 | |
| ... | ... | @@ -7581,6 +7604,10 @@ fn instantiateGenericCall( |
| 7581 | 7604 | if (call_tag == .call_always_tail) { |
| 7582 | 7605 | return sema.handleTailCall(block, call_src, func_ty, result); |
| 7583 | 7606 | } |
| 7607 | if (new_fn_info.return_type.isNoReturn()) { |
| 7608 | _ = try block.addNoOp(.unreach); |
| 7609 | return Air.Inst.Ref.unreachable_value; |
| 7610 | } |
| 7584 | 7611 | return result; |
| 7585 | 7612 | } |
| 7586 | 7613 | |
| ... | ... | @@ -23440,6 +23467,7 @@ pub const PanicId = enum { |
| 23440 | 23467 | for_len_mismatch, |
| 23441 | 23468 | memcpy_len_mismatch, |
| 23442 | 23469 | memcpy_alias, |
| 23470 | noreturn_returned, |
| 23443 | 23471 | }; |
| 23444 | 23472 | |
| 23445 | 23473 | fn addSafetyCheck( |
| ... | ... | @@ -23607,7 +23635,7 @@ fn panicIndexOutOfBounds( |
| 23607 | 23635 | try sema.safetyCheckFormatted(parent_block, ok, "panicOutOfBounds", &.{ index, len }); |
| 23608 | 23636 | } |
| 23609 | 23637 | |
| 23610 | | fn panicStartLargerThanEnd( |
| 23638 | fn panicStartGreaterThanEnd( |
| 23611 | 23639 | sema: *Sema, |
| 23612 | 23640 | parent_block: *Block, |
| 23613 | 23641 | start: Air.Inst.Ref, |
| ... | ... | @@ -29464,8 +29492,10 @@ fn analyzeSlice( |
| 29464 | 29492 | const slice_sentinel = if (sentinel_opt != .none) sentinel else null; |
| 29465 | 29493 | |
| 29466 | 29494 | // requirement: start <= end |
| 29495 | var need_start_gt_end_check = true; |
| 29467 | 29496 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { |
| 29468 | 29497 | if (try sema.resolveDefinedValue(block, start_src, start)) |start_val| { |
| 29498 | need_start_gt_end_check = false; |
| 29469 | 29499 | if (!by_length and !(try sema.compareAll(start_val, .lte, end_val, Type.usize))) { |
| 29470 | 29500 | return sema.fail( |
| 29471 | 29501 | block, |
| ... | ... | @@ -29519,9 +29549,9 @@ fn analyzeSlice( |
| 29519 | 29549 | } |
| 29520 | 29550 | } |
| 29521 | 29551 | |
| 29522 | | if (!by_length and block.wantSafety() and !block.is_comptime) { |
| 29552 | if (!by_length and block.wantSafety() and !block.is_comptime and need_start_gt_end_check) { |
| 29523 | 29553 | // requirement: start <= end |
| 29524 | | try sema.panicStartLargerThanEnd(block, start, end); |
| 29554 | try sema.panicStartGreaterThanEnd(block, start, end); |
| 29525 | 29555 | } |
| 29526 | 29556 | const new_len = if (by_length) |
| 29527 | 29557 | try sema.coerce(block, Type.usize, uncasted_end_opt, end_src) |