| ... | @@ -923,6 +923,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { | ... | @@ -923,6 +923,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { |
| 923 | return buf_create_from_str("frame too small"); | 923 | return buf_create_from_str("frame too small"); |
| 924 | case PanicMsgIdResumedFnPendingAwait: | 924 | case PanicMsgIdResumedFnPendingAwait: |
| 925 | return buf_create_from_str("resumed an async function which can only be awaited"); | 925 | return buf_create_from_str("resumed an async function which can only be awaited"); |
| | 926 | case PanicMsgIdBadNoAsyncCall: |
| | 927 | return buf_create_from_str("async function called with noasync suspended"); |
| 926 | } | 928 | } |
| 927 | zig_unreachable(); | 929 | zig_unreachable(); |
| 928 | } | 930 | } |
| ... | @@ -4067,6 +4069,25 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -4067,6 +4069,25 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 4067 | } else if (instruction->modifier == CallModifierNoAsync && !fn_is_async(g->cur_fn)) { | 4069 | } else if (instruction->modifier == CallModifierNoAsync && !fn_is_async(g->cur_fn)) { |
| 4068 | gen_resume(g, fn_val, frame_result_loc, ResumeIdCall); | 4070 | gen_resume(g, fn_val, frame_result_loc, ResumeIdCall); |
| 4069 | | 4071 | |
| | 4072 | if (ir_want_runtime_safety(g, &instruction->base)) { |
| | 4073 | LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, |
| | 4074 | frame_awaiter_index, ""); |
| | 4075 | LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref); |
| | 4076 | LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXchg, awaiter_ptr, |
| | 4077 | all_ones, LLVMAtomicOrderingRelease); |
| | 4078 | LLVMValueRef ok_val = LLVMBuildICmp(g->builder, LLVMIntEQ, prev_val, all_ones, ""); |
| | 4079 | |
| | 4080 | LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncPanic"); |
| | 4081 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncOk"); |
| | 4082 | LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block); |
| | 4083 | |
| | 4084 | // The async function suspended, but this noasync call asserted it wouldn't. |
| | 4085 | LLVMPositionBuilderAtEnd(g->builder, bad_block); |
| | 4086 | gen_safety_crash(g, PanicMsgIdBadNoAsyncCall); |
| | 4087 | |
| | 4088 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| | 4089 | } |
| | 4090 | |
| 4070 | ZigType *result_type = instruction->base.value.type; | 4091 | ZigType *result_type = instruction->base.value.type; |
| 4071 | ZigType *ptr_result_type = get_pointer_to_type(g, result_type, true); | 4092 | ZigType *ptr_result_type = get_pointer_to_type(g, result_type, true); |
| 4072 | return gen_await_early_return(g, &instruction->base, frame_result_loc, | 4093 | return gen_await_early_return(g, &instruction->base, frame_result_loc, |