authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-08 12:02:56-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-08 12:02:56-04:00
logd813805f775b74416337ce8f1bd7b2e789caf185
tree8c45e975c730fde6196e925ffe409e31255b4a11
parent34bfdf193aee4cb4fc931c6cc4ee82ef0a3a506f
signature Commit is signed but in an unrecognized format.

more debuggable safety for awaiting twice


2 files changed, 29 insertions(+), 5 deletions(-)

src/codegen.cpp+5-5
......@@ -2259,7 +2259,7 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
22592259
22602260 LLVMValueRef zero = LLVMConstNull(usize_type_ref);
22612261 LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref);
2262 LLVMValueRef prev_val = LLVMBuildAtomicRMW(g->builder, LLVMAtomicRMWBinOpXchg, g->cur_async_awaiter_ptr,
2262 LLVMValueRef prev_val = LLVMBuildAtomicRMW(g->builder, LLVMAtomicRMWBinOpXor, g->cur_async_awaiter_ptr,
22632263 all_ones, LLVMAtomicOrderingAcquire, g->is_single_threaded);
22642264
22652265 LLVMBasicBlockRef bad_return_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadReturn");
......@@ -2346,7 +2346,7 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
23462346 LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, masked_prev_val,
23472347 get_llvm_type(g, any_frame_type), "");
23482348 LLVMValueRef call_inst = gen_resume(g, nullptr, their_frame_ptr, ResumeIdReturn, nullptr);
2349 ZigLLVMSetTailCall(call_inst);
2349 LLVMSetTailCall(call_inst, true);
23502350 LLVMBuildRetVoid(g->builder);
23512351
23522352 return nullptr;
......@@ -3956,7 +3956,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
39563956 LLVMBasicBlockRef call_bb = gen_suspend_begin(g, "CallResume");
39573957
39583958 LLVMValueRef call_inst = gen_resume(g, fn_val, frame_result_loc, ResumeIdCall, nullptr);
3959 ZigLLVMSetTailCall(call_inst);
3959 LLVMSetTailCall(call_inst, true);
39603960 LLVMBuildRetVoid(g->builder);
39613961
39623962 LLVMPositionBuilderAtEnd(g->builder, call_bb);
......@@ -5456,7 +5456,7 @@ static LLVMValueRef ir_render_cancel(CodeGen *g, IrExecutable *executable, IrIns
54565456
54575457 LLVMPositionBuilderAtEnd(g->builder, early_return_block);
54585458 LLVMValueRef call_inst = gen_resume(g, nullptr, target_frame_ptr, ResumeIdAwaitEarlyReturn, awaiter_ored_val);
5459 ZigLLVMSetTailCall(call_inst);
5459 LLVMSetTailCall(call_inst, true);
54605460 LLVMBuildRetVoid(g->builder);
54615461
54625462 LLVMPositionBuilderAtEnd(g->builder, resume_bb);
......@@ -5524,7 +5524,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst
55245524 // Tail resume it now, so that it can complete.
55255525 LLVMPositionBuilderAtEnd(g->builder, early_return_block);
55265526 LLVMValueRef call_inst = gen_resume(g, nullptr, target_frame_ptr, ResumeIdAwaitEarlyReturn, awaiter_init_val);
5527 ZigLLVMSetTailCall(call_inst);
5527 LLVMSetTailCall(call_inst, true);
55285528 LLVMBuildRetVoid(g->builder);
55295529
55305530 // Rely on the target to resume us from suspension.
test/runtime_safety.zig+24
......@@ -1,6 +1,30 @@
11const tests = @import("tests.zig");
22
33pub fn addCases(cases: *tests.CompareOutputContext) void {
4 cases.addRuntimeSafety("awaiting twice",
5 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
6 \\ @import("std").os.exit(126);
7 \\}
8 \\var frame: anyframe = undefined;
9 \\
10 \\pub fn main() void {
11 \\ _ = async amain();
12 \\ resume frame;
13 \\}
14 \\
15 \\fn amain() void {
16 \\ var f = async func();
17 \\ await f;
18 \\ await f;
19 \\}
20 \\
21 \\fn func() void {
22 \\ suspend {
23 \\ frame = @frame();
24 \\ }
25 \\}
26 );
27
428 cases.addRuntimeSafety("@asyncCall with too small a frame",
529 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
630 \\ @import("std").os.exit(126);