authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-06 18:29:56-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-06 18:29:56-04:00
log17199b087915661c935f0970cc1e4eb29968a68d
tree8bac40ee50c809720fee1bbfbd23bbc4347500a1
parent400500a3afafca8178f13a7e4e1cd0ae7808aff2
signature Commit is signed but in an unrecognized format.

passing the error return trace async function test


5 files changed, 114 insertions(+), 95 deletions(-)

src/all_types.hpp+1-1
......@@ -1718,7 +1718,7 @@ struct CodeGen {
17181718 LLVMTargetMachineRef target_machine;
17191719 ZigLLVMDIFile *dummy_di_file;
17201720 LLVMValueRef cur_ret_ptr;
1721 LLVMValueRef cur_ret_ptr_ptr;
1721 LLVMValueRef cur_frame_ptr;
17221722 LLVMValueRef cur_fn_val;
17231723 LLVMValueRef cur_async_switch_instr;
17241724 LLVMValueRef cur_async_resume_index_ptr;
src/analyze.cpp+5
......@@ -5160,6 +5160,8 @@ static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) {
51605160}
51615161
51625162static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
5163 Error err;
5164
51635165 if (frame_type->data.frame.locals_struct != nullptr)
51645166 return ErrorNone;
51655167
......@@ -5286,6 +5288,9 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
52865288 continue;
52875289 }
52885290 }
5291 if ((err = type_resolve(g, child_type, ResolveStatusSizeKnown))) {
5292 return err;
5293 }
52895294 const char *name;
52905295 if (*instruction->name_hint == 0) {
52915296 name = buf_ptr(buf_sprintf("@local%" ZIG_PRI_usize, alloca_i));
src/codegen.cpp+37-31
......@@ -2088,17 +2088,19 @@ static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef tar
20882088static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
20892089 IrInstructionReturnBegin *instruction)
20902090{
2091 if (!fn_is_async(g->cur_fn)) return nullptr;
2091 bool ret_type_has_bits = instruction->operand != nullptr &&
2092 type_has_bits(instruction->operand->value.type);
2093
2094 if (!fn_is_async(g->cur_fn)) {
2095 return ret_type_has_bits ? ir_llvm_value(g, instruction->operand) : nullptr;
2096 }
20922097
20932098 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
20942099
2095 bool ret_type_has_bits = instruction->operand != nullptr &&
2096 type_has_bits(instruction->operand->value.type);
20972100 ZigType *ret_type = ret_type_has_bits ? instruction->operand->value.type : nullptr;
20982101 if (ret_type_has_bits && !handle_is_ptr(ret_type)) {
20992102 // It's a scalar, so it didn't get written to the result ptr. Do that before the atomic rmw.
2100 LLVMValueRef result_ptr = LLVMBuildLoad(g->builder, g->cur_ret_ptr_ptr, "");
2101 LLVMBuildStore(g->builder, ir_llvm_value(g, instruction->operand), result_ptr);
2103 LLVMBuildStore(g->builder, ir_llvm_value(g, instruction->operand), g->cur_ret_ptr);
21022104 }
21032105
21042106 // Prepare to be suspended. We might end up not having to suspend though.
......@@ -2147,7 +2149,11 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
21472149 LLVMBasicBlockRef incoming_blocks[] = { after_resume_block, switch_bb };
21482150 LLVMAddIncoming(g->cur_async_prev_val, incoming_values, incoming_blocks, 2);
21492151
2150 return nullptr;
2152 if (!ret_type_has_bits) {
2153 return nullptr;
2154 }
2155
2156 return get_handle_value(g, g->cur_ret_ptr, ret_type, get_pointer_to_type(g, ret_type, true));
21512157}
21522158
21532159static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *instruction) {
......@@ -2166,17 +2172,16 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
21662172 // If the awaiter result pointer is non-null, we need to copy the result to there.
21672173 LLVMBasicBlockRef copy_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResult");
21682174 LLVMBasicBlockRef copy_end_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResultEnd");
2169 LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_ret_start + 1, "");
2175 LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, coro_ret_start + 1, "");
21702176 LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad(g->builder, awaiter_ret_ptr_ptr, "");
21712177 LLVMValueRef zero_ptr = LLVMConstNull(LLVMTypeOf(awaiter_ret_ptr));
21722178 LLVMValueRef need_copy_bit = LLVMBuildICmp(g->builder, LLVMIntNE, awaiter_ret_ptr, zero_ptr, "");
21732179 LLVMBuildCondBr(g->builder, need_copy_bit, copy_block, copy_end_block);
21742180
21752181 LLVMPositionBuilderAtEnd(g->builder, copy_block);
2176 LLVMValueRef ret_ptr = LLVMBuildLoad(g->builder, g->cur_ret_ptr_ptr, "");
21772182 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
21782183 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, awaiter_ret_ptr, ptr_u8, "");
2179 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, ret_ptr, ptr_u8, "");
2184 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, g->cur_ret_ptr, ptr_u8, "");
21802185 bool is_volatile = false;
21812186 uint32_t abi_align = get_abi_alignment(g, ret_type);
21822187 LLVMValueRef byte_count_val = LLVMConstInt(usize_type_ref, type_size(g, ret_type), false);
......@@ -3385,10 +3390,6 @@ static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutable *executable,
33853390 if (!type_has_bits(instruction->base.value.type))
33863391 return nullptr;
33873392 src_assert(g->cur_ret_ptr != nullptr, instruction->base.source_node);
3388 if (fn_is_async(g->cur_fn)) {
3389 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_ret_start, "");
3390 return LLVMBuildLoad(g->builder, ptr_ptr, "");
3391 }
33923393 return g->cur_ret_ptr;
33933394}
33943395
......@@ -3547,7 +3548,7 @@ static void render_async_spills(CodeGen *g) {
35473548 continue;
35483549 }
35493550
3550 var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, async_var_index,
3551 var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, async_var_index,
35513552 buf_ptr(&var->name));
35523553 async_var_index += 1;
35533554 if (var->decl_node) {
......@@ -3578,7 +3579,7 @@ static void render_async_spills(CodeGen *g) {
35783579 continue;
35793580 }
35803581 }
3581 instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, async_var_index,
3582 instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, async_var_index,
35823583 instruction->name_hint);
35833584 async_var_index += 1;
35843585 }
......@@ -3697,7 +3698,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
36973698 // initialization.
36983699 } else if (callee_is_async) {
36993700 frame_result_loc = ir_llvm_value(g, instruction->frame_result_loc);
3700 awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_ret_ptr, usize_type_ref, ""); // caller's own frame pointer
3701 awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, ""); // caller's own frame pointer
37013702 if (ret_has_bits) {
37023703 if (result_loc == nullptr) {
37033704 // return type is a scalar, but we still need a pointer to it. Use the async fn frame.
......@@ -4850,7 +4851,7 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutable *executable
48504851}
48514852
48524853static LLVMValueRef ir_render_handle(CodeGen *g, IrExecutable *executable, IrInstructionFrameHandle *instruction) {
4853 return g->cur_ret_ptr;
4854 return g->cur_frame_ptr;
48544855}
48554856
48564857static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp *instruction) {
......@@ -5335,7 +5336,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst
53355336 }
53365337
53375338 // caller's own frame pointer
5338 LLVMValueRef awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_ret_ptr, usize_type_ref, "");
5339 LLVMValueRef awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, "");
53395340 LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, coro_awaiter_index, "");
53405341 LLVMValueRef prev_val = LLVMBuildAtomicRMW(g->builder, LLVMAtomicRMWBinOpXchg, awaiter_ptr, awaiter_init_val,
53415342 LLVMAtomicOrderingRelease, g->is_single_threaded);
......@@ -6710,13 +6711,17 @@ static void do_code_gen(CodeGen *g) {
67106711
67116712 bool is_async = fn_is_async(fn_table_entry);
67126713
6713 if (want_sret || is_async) {
6714 g->cur_ret_ptr = LLVMGetParam(fn, 0);
6715 } else if (handle_is_ptr(fn_type_id->return_type)) {
6716 g->cur_ret_ptr = build_alloca(g, fn_type_id->return_type, "result", 0);
6717 // TODO add debug info variable for this
6714 if (is_async) {
6715 g->cur_frame_ptr = LLVMGetParam(fn, 0);
67186716 } else {
6719 g->cur_ret_ptr = nullptr;
6717 if (want_sret) {
6718 g->cur_ret_ptr = LLVMGetParam(fn, 0);
6719 } else if (handle_is_ptr(fn_type_id->return_type)) {
6720 g->cur_ret_ptr = build_alloca(g, fn_type_id->return_type, "result", 0);
6721 // TODO add debug info variable for this
6722 } else {
6723 g->cur_ret_ptr = nullptr;
6724 }
67206725 }
67216726
67226727 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry);
......@@ -6870,21 +6875,22 @@ static void do_code_gen(CodeGen *g) {
68706875
68716876 LLVMPositionBuilderAtEnd(g->builder, g->cur_preamble_llvm_block);
68726877 render_async_spills(g);
6873 g->cur_async_awaiter_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_awaiter_index, "");
6874 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_resume_index, "");
6878 g->cur_async_awaiter_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, coro_awaiter_index, "");
6879 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, coro_resume_index, "");
68756880 g->cur_async_resume_index_ptr = resume_index_ptr;
68766881
68776882 if (type_has_bits(fn_type_id->return_type)) {
6878 g->cur_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_ret_start, "");
6883 LLVMValueRef cur_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, coro_ret_start, "");
6884 g->cur_ret_ptr = LLVMBuildLoad(g->builder, cur_ret_ptr_ptr, "");
68796885 }
68806886 if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
68816887 uint32_t trace_field_index = frame_index_trace_arg(g, fn_type_id->return_type);
6882 g->cur_err_ret_trace_val_arg = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, trace_field_index, "");
6888 g->cur_err_ret_trace_val_arg = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, trace_field_index, "");
68836889 }
68846890 uint32_t trace_field_index_stack = UINT32_MAX;
68856891 if (codegen_fn_has_err_ret_tracing_stack(g, fn_table_entry, true)) {
68866892 trace_field_index_stack = frame_index_trace_stack(g, fn_type_id);
6887 g->cur_err_ret_trace_val_stack = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr,
6893 g->cur_err_ret_trace_val_stack = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
68886894 trace_field_index_stack, "");
68896895 }
68906896
......@@ -6898,9 +6904,9 @@ static void do_code_gen(CodeGen *g) {
68986904 g->cur_resume_block_count += 1;
68996905 LLVMPositionBuilderAtEnd(g->builder, entry_block->llvm_block);
69006906 if (trace_field_index_stack != UINT32_MAX) {
6901 LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr,
6907 LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
69026908 trace_field_index_stack, "");
6903 LLVMValueRef trace_field_addrs = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr,
6909 LLVMValueRef trace_field_addrs = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
69046910 trace_field_index_stack + 1, "");
69056911
69066912 LLVMValueRef index_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 0, "");
src/ir.cpp+37-29
......@@ -1129,8 +1129,6 @@ static IrInstruction *ir_build_return_begin(IrBuilder *irb, Scope *scope, AstNod
11291129 IrInstruction *operand)
11301130{
11311131 IrInstructionReturnBegin *return_instruction = ir_build_instruction<IrInstructionReturnBegin>(irb, scope, source_node);
1132 return_instruction->base.value.type = irb->codegen->builtin_types.entry_void;
1133 return_instruction->base.value.special = ConstValSpecialStatic;
11341132 return_instruction->operand = operand;
11351133
11361134 ir_ref_instruction(operand, irb->current_basic_block);
......@@ -3480,7 +3478,8 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
34803478 return_value = ir_build_const_void(irb, scope, node);
34813479 }
34823480
3483 ir_build_return_begin(irb, scope, node, return_value);
3481 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value));
3482 return_value = ir_build_return_begin(irb, scope, node, return_value);
34843483
34853484 size_t defer_counts[2];
34863485 ir_count_defers(irb, scope, outer_scope, defer_counts);
......@@ -3514,14 +3513,12 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
35143513 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
35153514
35163515 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block);
3517 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value));
35183516 IrInstruction *result = ir_build_return(irb, scope, node, return_value);
35193517 result_loc_ret->base.source_instruction = result;
35203518 return result;
35213519 } else {
35223520 // generate unconditional defers
35233521 ir_gen_defers_for_block(irb, scope, outer_scope, false);
3524 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value));
35253522 IrInstruction *result = ir_build_return(irb, scope, node, return_value);
35263523 result_loc_ret->base.source_instruction = result;
35273524 return result;
......@@ -3549,7 +3546,8 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
35493546 ir_set_cursor_at_end_and_append_block(irb, return_block);
35503547 IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr);
35513548 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);
3552 ir_build_return_begin(irb, scope, node, err_val);
3549 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val));
3550 err_val = ir_build_return_begin(irb, scope, node, err_val);
35533551 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) {
35543552 ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1);
35553553 result_loc_ret->base.id = ResultLocIdReturn;
......@@ -3559,7 +3557,6 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
35593557 if (irb->codegen->have_err_ret_tracing && !should_inline) {
35603558 ir_build_save_err_ret_addr(irb, scope, node);
35613559 }
3562 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val));
35633560 IrInstruction *ret_inst = ir_build_return(irb, scope, node, err_val);
35643561 result_loc_ret->base.source_instruction = ret_inst;
35653562 }
......@@ -4972,7 +4969,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
49724969 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval, result_loc);
49734970 case BuiltinFnIdFrameHandle:
49744971 if (!irb->exec->fn_entry) {
4975 add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition"));
4972 add_node_error(irb->codegen, node, buf_sprintf("@frame() called outside of function definition"));
49764973 return irb->codegen->invalid_instruction;
49774974 }
49784975 return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval, result_loc);
......@@ -8101,9 +8098,9 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
81018098 return false;
81028099
81038100 if (!instr_is_unreachable(result)) {
8104 ir_mark_gen(ir_build_return_begin(irb, scope, node, result));
8105 // no need for save_err_ret_addr because this cannot return error
81068101 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result));
8102 result = ir_mark_gen(ir_build_return_begin(irb, scope, node, result));
8103 // no need for save_err_ret_addr because this cannot return error
81078104 ir_mark_gen(ir_build_return(irb, scope, result->source_node, result));
81088105 }
81098106
......@@ -9789,6 +9786,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
97899786
97909787 ZigType *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type;
97919788 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;
9789 if (prev_err_set_type == cur_err_set_type)
9790 continue;
97929791
97939792 if (!resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) {
97949793 return ira->codegen->builtin_types.entry_invalid;
......@@ -12614,6 +12613,14 @@ static IrInstruction *ir_analyze_instruction_return_begin(IrAnalyze *ira, IrInst
1261412613 if (type_is_invalid(operand->value.type))
1261512614 return ira->codegen->invalid_instruction;
1261612615
12616 if (!instr_is_comptime(operand) && handle_is_ptr(ira->explicit_return_type)) {
12617 // result location mechanism took care of it.
12618 IrInstruction *result = ir_build_return_begin(&ira->new_irb, instruction->base.scope,
12619 instruction->base.source_node, operand);
12620 copy_const_val(&result->value, &operand->value, true);
12621 return result;
12622 }
12623
1261712624 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type);
1261812625 if (type_is_invalid(casted_operand->value.type)) {
1261912626 AstNode *source_node = ira->explicit_return_type_source_node;
......@@ -12625,8 +12632,18 @@ static IrInstruction *ir_analyze_instruction_return_begin(IrAnalyze *ira, IrInst
1262512632 return ir_unreach_error(ira);
1262612633 }
1262712634
12628 return ir_build_return_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node,
12629 casted_operand);
12635 if (casted_operand->value.special == ConstValSpecialRuntime &&
12636 casted_operand->value.type->id == ZigTypeIdPointer &&
12637 casted_operand->value.data.rh_ptr == RuntimeHintPtrStack)
12638 {
12639 ir_add_error(ira, casted_operand, buf_sprintf("function returns address of local variable"));
12640 return ir_unreach_error(ira);
12641 }
12642
12643 IrInstruction *result = ir_build_return_begin(&ira->new_irb, instruction->base.scope,
12644 instruction->base.source_node, casted_operand);
12645 copy_const_val(&result->value, &casted_operand->value, true);
12646 return result;
1263012647}
1263112648
1263212649static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructionReturn *instruction) {
......@@ -12642,21 +12659,8 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
1264212659 return ir_finish_anal(ira, result);
1264312660 }
1264412661
12645 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type);
12646 if (type_is_invalid(casted_operand->value.type)) {
12647 // error already reported by IrInstructionReturnBegin
12648 return ir_unreach_error(ira);
12649 }
12650
12651 if (casted_operand->value.special == ConstValSpecialRuntime &&
12652 casted_operand->value.type->id == ZigTypeIdPointer &&
12653 casted_operand->value.data.rh_ptr == RuntimeHintPtrStack)
12654 {
12655 ir_add_error(ira, casted_operand, buf_sprintf("function returns address of local variable"));
12656 return ir_unreach_error(ira);
12657 }
1265812662 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
12659 instruction->base.source_node, casted_operand);
12663 instruction->base.source_node, operand);
1266012664 result->value.type = ira->codegen->builtin_types.entry_unreachable;
1266112665 return ir_finish_anal(ira, result);
1266212666}
......@@ -14612,8 +14616,12 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
1461214616 if ((err = type_resolve(ira->codegen, ira->explicit_return_type, ResolveStatusZeroBitsKnown))) {
1461314617 return ira->codegen->invalid_instruction;
1461414618 }
14615 if (!type_has_bits(ira->explicit_return_type) || !handle_is_ptr(ira->explicit_return_type))
14616 return nullptr;
14619 if (!type_has_bits(ira->explicit_return_type) || !handle_is_ptr(ira->explicit_return_type)) {
14620 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
14621 if (fn_entry == nullptr || fn_entry->inferred_async_node == nullptr) {
14622 return nullptr;
14623 }
14624 }
1461714625
1461814626 ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false);
1461914627 result_loc->written = true;
......@@ -24510,7 +24518,7 @@ static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstruction
2451024518 IrInstruction *result_loc;
2451124519 if (type_has_bits(result_type)) {
2451224520 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
24513 result_type, nullptr, true, false, true);
24521 result_type, nullptr, true, true, true);
2451424522 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))
2451524523 return result_loc;
2451624524 } else {
test/stage1/behavior/coroutines.zig+34-34
......@@ -334,40 +334,40 @@ test "async fn with inferred error set" {
334334 S.doTheTest();
335335}
336336
337//test "error return trace across suspend points - early return" {
338// const p = nonFailing();
339// resume p;
340// const p2 = async printTrace(p);
341//}
342//
343//test "error return trace across suspend points - async return" {
344// const p = nonFailing();
345// const p2 = async printTrace(p);
346// resume p;
347//}
348//
349//fn nonFailing() (anyframe->anyerror!void) {
350// const Static = struct {
351// var frame: @Frame(suspendThenFail) = undefined;
352// };
353// Static.frame = async suspendThenFail();
354// return &Static.frame;
355//}
356//async fn suspendThenFail() anyerror!void {
357// suspend;
358// return error.Fail;
359//}
360//async fn printTrace(p: anyframe->(anyerror!void)) void {
361// (await p) catch |e| {
362// std.testing.expect(e == error.Fail);
363// if (@errorReturnTrace()) |trace| {
364// expect(trace.index == 1);
365// } else switch (builtin.mode) {
366// .Debug, .ReleaseSafe => @panic("expected return trace"),
367// .ReleaseFast, .ReleaseSmall => {},
368// }
369// };
370//}
337test "error return trace across suspend points - early return" {
338 const p = nonFailing();
339 resume p;
340 const p2 = async printTrace(p);
341}
342
343test "error return trace across suspend points - async return" {
344 const p = nonFailing();
345 const p2 = async printTrace(p);
346 resume p;
347}
348
349fn nonFailing() (anyframe->anyerror!void) {
350 const Static = struct {
351 var frame: @Frame(suspendThenFail) = undefined;
352 };
353 Static.frame = async suspendThenFail();
354 return &Static.frame;
355}
356async fn suspendThenFail() anyerror!void {
357 suspend;
358 return error.Fail;
359}
360async fn printTrace(p: anyframe->(anyerror!void)) void {
361 (await p) catch |e| {
362 std.testing.expect(e == error.Fail);
363 if (@errorReturnTrace()) |trace| {
364 expect(trace.index == 1);
365 } else switch (builtin.mode) {
366 .Debug, .ReleaseSafe => @panic("expected return trace"),
367 .ReleaseFast, .ReleaseSmall => {},
368 }
369 };
370}
371371
372372test "break from suspend" {
373373 var my_result: i32 = 1;