| ... | @@ -7080,15 +7080,38 @@ fn analyzeCall( | ... | @@ -7080,15 +7080,38 @@ fn analyzeCall( |
| 7080 | } }, | 7080 | } }, |
| 7081 | }); | 7081 | }); |
| 7082 | sema.appendRefsAssumeCapacity(args); | 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 | break :res func_inst; | 7109 | break :res func_inst; |
| 7084 | }; | 7110 | }; |
| 7085 | | 7111 | |
| 7086 | if (ensure_result_used) { | 7112 | if (ensure_result_used) { |
| 7087 | try sema.ensureResultUsed(block, sema.typeOf(result), call_src); | 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 | return result; | 7115 | return result; |
| 7093 | } | 7116 | } |
| 7094 | | 7117 | |
| ... | @@ -7581,6 +7604,10 @@ fn instantiateGenericCall( | ... | @@ -7581,6 +7604,10 @@ fn instantiateGenericCall( |
| 7581 | if (call_tag == .call_always_tail) { | 7604 | if (call_tag == .call_always_tail) { |
| 7582 | return sema.handleTailCall(block, call_src, func_ty, result); | 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 | return result; | 7611 | return result; |
| 7585 | } | 7612 | } |
| 7586 | | 7613 | |
| ... | @@ -23440,6 +23467,7 @@ pub const PanicId = enum { | ... | @@ -23440,6 +23467,7 @@ pub const PanicId = enum { |
| 23440 | for_len_mismatch, | 23467 | for_len_mismatch, |
| 23441 | memcpy_len_mismatch, | 23468 | memcpy_len_mismatch, |
| 23442 | memcpy_alias, | 23469 | memcpy_alias, |
| | 23470 | noreturn_returned, |
| 23443 | }; | 23471 | }; |
| 23444 | | 23472 | |
| 23445 | fn addSafetyCheck( | 23473 | fn addSafetyCheck( |
| ... | @@ -23607,7 +23635,7 @@ fn panicIndexOutOfBounds( | ... | @@ -23607,7 +23635,7 @@ fn panicIndexOutOfBounds( |
| 23607 | try sema.safetyCheckFormatted(parent_block, ok, "panicOutOfBounds", &.{ index, len }); | 23635 | try sema.safetyCheckFormatted(parent_block, ok, "panicOutOfBounds", &.{ index, len }); |
| 23608 | } | 23636 | } |
| 23609 | | 23637 | |
| 23610 | fn panicStartLargerThanEnd( | 23638 | fn panicStartGreaterThanEnd( |
| 23611 | sema: *Sema, | 23639 | sema: *Sema, |
| 23612 | parent_block: *Block, | 23640 | parent_block: *Block, |
| 23613 | start: Air.Inst.Ref, | 23641 | start: Air.Inst.Ref, |
| ... | @@ -29464,8 +29492,10 @@ fn analyzeSlice( | ... | @@ -29464,8 +29492,10 @@ fn analyzeSlice( |
| 29464 | const slice_sentinel = if (sentinel_opt != .none) sentinel else null; | 29492 | const slice_sentinel = if (sentinel_opt != .none) sentinel else null; |
| 29465 | | 29493 | |
| 29466 | // requirement: start <= end | 29494 | // requirement: start <= end |
| | 29495 | var need_start_gt_end_check = true; |
| 29467 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { | 29496 | if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { |
| 29468 | if (try sema.resolveDefinedValue(block, start_src, start)) |start_val| { | 29497 | if (try sema.resolveDefinedValue(block, start_src, start)) |start_val| { |
| | 29498 | need_start_gt_end_check = false; |
| 29469 | if (!by_length and !(try sema.compareAll(start_val, .lte, end_val, Type.usize))) { | 29499 | if (!by_length and !(try sema.compareAll(start_val, .lte, end_val, Type.usize))) { |
| 29470 | return sema.fail( | 29500 | return sema.fail( |
| 29471 | block, | 29501 | block, |
| ... | @@ -29519,9 +29549,9 @@ fn analyzeSlice( | ... | @@ -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 | // requirement: start <= end | 29553 | // requirement: start <= end |
| 29524 | try sema.panicStartLargerThanEnd(block, start, end); | 29554 | try sema.panicStartGreaterThanEnd(block, start, end); |
| 29525 | } | 29555 | } |
| 29526 | const new_len = if (by_length) | 29556 | const new_len = if (by_length) |
| 29527 | try sema.coerce(block, Type.usize, uncasted_end_opt, end_src) | 29557 | try sema.coerce(block, Type.usize, uncasted_end_opt, end_src) |