| ... | @@ -7055,15 +7055,38 @@ fn analyzeCall( | ... | @@ -7055,15 +7055,38 @@ fn analyzeCall( |
| 7055 | } }, | 7055 | } }, |
| 7056 | }); | 7056 | }); |
| 7057 | sema.appendRefsAssumeCapacity(args); | 7057 | sema.appendRefsAssumeCapacity(args); |
| | 7058 | |
| | 7059 | if (call_tag == .call_always_tail) { |
| | 7060 | if (ensure_result_used) { |
| | 7061 | try sema.ensureResultUsed(block, sema.typeOf(func_inst), call_src); |
| | 7062 | } |
| | 7063 | return sema.handleTailCall(block, call_src, func_ty, func_inst); |
| | 7064 | } else if (block.wantSafety() and func_ty_info.return_type.isNoReturn()) { |
| | 7065 | // Function pointers and extern functions aren't guaranteed to |
| | 7066 | // actually be noreturn so we add a safety check for them. |
| | 7067 | check: { |
| | 7068 | var func_val = (try sema.resolveMaybeUndefVal(func)) orelse break :check; |
| | 7069 | switch (func_val.tag()) { |
| | 7070 | .function, .decl_ref => { |
| | 7071 | _ = try block.addNoOp(.unreach); |
| | 7072 | return Air.Inst.Ref.unreachable_value; |
| | 7073 | }, |
| | 7074 | else => break :check, |
| | 7075 | } |
| | 7076 | } |
| | 7077 | |
| | 7078 | try sema.safetyPanic(block, .noreturn_returned); |
| | 7079 | return Air.Inst.Ref.unreachable_value; |
| | 7080 | } else if (func_ty_info.return_type.isNoReturn()) { |
| | 7081 | _ = try block.addNoOp(.unreach); |
| | 7082 | return Air.Inst.Ref.unreachable_value; |
| | 7083 | } |
| 7058 | break :res func_inst; | 7084 | break :res func_inst; |
| 7059 | }; | 7085 | }; |
| 7060 | | 7086 | |
| 7061 | if (ensure_result_used) { | 7087 | if (ensure_result_used) { |
| 7062 | try sema.ensureResultUsed(block, sema.typeOf(result), call_src); | 7088 | try sema.ensureResultUsed(block, sema.typeOf(result), call_src); |
| 7063 | } | 7089 | } |
| 7064 | if (call_tag == .call_always_tail) { | | |
| 7065 | return sema.handleTailCall(block, call_src, func_ty, result); | | |
| 7066 | } | | |
| 7067 | return result; | 7090 | return result; |
| 7068 | } | 7091 | } |
| 7069 | | 7092 | |
| ... | @@ -7556,6 +7579,10 @@ fn instantiateGenericCall( | ... | @@ -7556,6 +7579,10 @@ fn instantiateGenericCall( |
| 7556 | if (call_tag == .call_always_tail) { | 7579 | if (call_tag == .call_always_tail) { |
| 7557 | return sema.handleTailCall(block, call_src, func_ty, result); | 7580 | return sema.handleTailCall(block, call_src, func_ty, result); |
| 7558 | } | 7581 | } |
| | 7582 | if (new_fn_info.return_type.isNoReturn()) { |
| | 7583 | _ = try block.addNoOp(.unreach); |
| | 7584 | return Air.Inst.Ref.unreachable_value; |
| | 7585 | } |
| 7559 | return result; | 7586 | return result; |
| 7560 | } | 7587 | } |
| 7561 | | 7588 | |
| ... | @@ -23441,6 +23468,7 @@ pub const PanicId = enum { | ... | @@ -23441,6 +23468,7 @@ pub const PanicId = enum { |
| 23441 | for_len_mismatch, | 23468 | for_len_mismatch, |
| 23442 | memcpy_len_mismatch, | 23469 | memcpy_len_mismatch, |
| 23443 | memcpy_alias, | 23470 | memcpy_alias, |
| | 23471 | noreturn_returned, |
| 23444 | }; | 23472 | }; |
| 23445 | | 23473 | |
| 23446 | fn addSafetyCheck( | 23474 | fn addSafetyCheck( |