more debuggable safety for awaiting twice
parent
34bfdf193a
commit
d813805f77
|
@ -2259,7 +2259,7 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
|
|||
|
||||
LLVMValueRef zero = LLVMConstNull(usize_type_ref);
|
||||
LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref);
|
||||
LLVMValueRef prev_val = LLVMBuildAtomicRMW(g->builder, LLVMAtomicRMWBinOpXchg, g->cur_async_awaiter_ptr,
|
||||
LLVMValueRef prev_val = LLVMBuildAtomicRMW(g->builder, LLVMAtomicRMWBinOpXor, g->cur_async_awaiter_ptr,
|
||||
all_ones, LLVMAtomicOrderingAcquire, g->is_single_threaded);
|
||||
|
||||
LLVMBasicBlockRef bad_return_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadReturn");
|
||||
|
@ -2346,7 +2346,7 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
|
|||
LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, masked_prev_val,
|
||||
get_llvm_type(g, any_frame_type), "");
|
||||
LLVMValueRef call_inst = gen_resume(g, nullptr, their_frame_ptr, ResumeIdReturn, nullptr);
|
||||
ZigLLVMSetTailCall(call_inst);
|
||||
LLVMSetTailCall(call_inst, true);
|
||||
LLVMBuildRetVoid(g->builder);
|
||||
|
||||
return nullptr;
|
||||
|
@ -3956,7 +3956,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
|
|||
LLVMBasicBlockRef call_bb = gen_suspend_begin(g, "CallResume");
|
||||
|
||||
LLVMValueRef call_inst = gen_resume(g, fn_val, frame_result_loc, ResumeIdCall, nullptr);
|
||||
ZigLLVMSetTailCall(call_inst);
|
||||
LLVMSetTailCall(call_inst, true);
|
||||
LLVMBuildRetVoid(g->builder);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, call_bb);
|
||||
|
@ -5456,7 +5456,7 @@ static LLVMValueRef ir_render_cancel(CodeGen *g, IrExecutable *executable, IrIns
|
|||
|
||||
LLVMPositionBuilderAtEnd(g->builder, early_return_block);
|
||||
LLVMValueRef call_inst = gen_resume(g, nullptr, target_frame_ptr, ResumeIdAwaitEarlyReturn, awaiter_ored_val);
|
||||
ZigLLVMSetTailCall(call_inst);
|
||||
LLVMSetTailCall(call_inst, true);
|
||||
LLVMBuildRetVoid(g->builder);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, resume_bb);
|
||||
|
@ -5524,7 +5524,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst
|
|||
// Tail resume it now, so that it can complete.
|
||||
LLVMPositionBuilderAtEnd(g->builder, early_return_block);
|
||||
LLVMValueRef call_inst = gen_resume(g, nullptr, target_frame_ptr, ResumeIdAwaitEarlyReturn, awaiter_init_val);
|
||||
ZigLLVMSetTailCall(call_inst);
|
||||
LLVMSetTailCall(call_inst, true);
|
||||
LLVMBuildRetVoid(g->builder);
|
||||
|
||||
// Rely on the target to resume us from suspension.
|
||||
|
|
|
@ -1,6 +1,30 @@
|
|||
const tests = @import("tests.zig");
|
||||
|
||||
pub fn addCases(cases: *tests.CompareOutputContext) void {
|
||||
cases.addRuntimeSafety("awaiting twice",
|
||||
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\var frame: anyframe = undefined;
|
||||
\\
|
||||
\\pub fn main() void {
|
||||
\\ _ = async amain();
|
||||
\\ resume frame;
|
||||
\\}
|
||||
\\
|
||||
\\fn amain() void {
|
||||
\\ var f = async func();
|
||||
\\ await f;
|
||||
\\ await f;
|
||||
\\}
|
||||
\\
|
||||
\\fn func() void {
|
||||
\\ suspend {
|
||||
\\ frame = @frame();
|
||||
\\ }
|
||||
\\}
|
||||
);
|
||||
|
||||
cases.addRuntimeSafety("@asyncCall with too small a frame",
|
||||
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
|
||||
\\ @import("std").os.exit(126);
|
||||
|
|
Loading…
Reference in New Issue