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 {...@@ -1718,7 +1718,7 @@ struct CodeGen {
1718 LLVMTargetMachineRef target_machine;1718 LLVMTargetMachineRef target_machine;
1719 ZigLLVMDIFile *dummy_di_file;1719 ZigLLVMDIFile *dummy_di_file;
1720 LLVMValueRef cur_ret_ptr;1720 LLVMValueRef cur_ret_ptr;
1721 LLVMValueRef cur_ret_ptr_ptr;1721 LLVMValueRef cur_frame_ptr;
1722 LLVMValueRef cur_fn_val;1722 LLVMValueRef cur_fn_val;
1723 LLVMValueRef cur_async_switch_instr;1723 LLVMValueRef cur_async_switch_instr;
1724 LLVMValueRef cur_async_resume_index_ptr;1724 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) {...@@ -5160,6 +5160,8 @@ static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) {
5160}5160}
51615161
5162static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {5162static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
5163 Error err;
5164
5163 if (frame_type->data.frame.locals_struct != nullptr)5165 if (frame_type->data.frame.locals_struct != nullptr)
5164 return ErrorNone;5166 return ErrorNone;
51655167
...@@ -5286,6 +5288,9 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {...@@ -5286,6 +5288,9 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
5286 continue;5288 continue;
5287 }5289 }
5288 }5290 }
5291 if ((err = type_resolve(g, child_type, ResolveStatusSizeKnown))) {
5292 return err;
5293 }
5289 const char *name;5294 const char *name;
5290 if (*instruction->name_hint == 0) {5295 if (*instruction->name_hint == 0) {
5291 name = buf_ptr(buf_sprintf("@local%" ZIG_PRI_usize, alloca_i));5296 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...@@ -2088,17 +2088,19 @@ static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef tar
2088static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,2088static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
2089 IrInstructionReturnBegin *instruction)2089 IrInstructionReturnBegin *instruction)
2090{2090{
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
2093 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;2098 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);
2097 ZigType *ret_type = ret_type_has_bits ? instruction->operand->value.type : nullptr;2100 ZigType *ret_type = ret_type_has_bits ? instruction->operand->value.type : nullptr;
2098 if (ret_type_has_bits && !handle_is_ptr(ret_type)) {2101 if (ret_type_has_bits && !handle_is_ptr(ret_type)) {
2099 // It's a scalar, so it didn't get written to the result ptr. Do that before the atomic rmw.2102 // 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, "");2103 LLVMBuildStore(g->builder, ir_llvm_value(g, instruction->operand), g->cur_ret_ptr);
2101 LLVMBuildStore(g->builder, ir_llvm_value(g, instruction->operand), result_ptr);
2102 }2104 }
21032105
2104 // Prepare to be suspended. We might end up not having to suspend though.2106 // 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,...@@ -2147,7 +2149,11 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
2147 LLVMBasicBlockRef incoming_blocks[] = { after_resume_block, switch_bb };2149 LLVMBasicBlockRef incoming_blocks[] = { after_resume_block, switch_bb };
2148 LLVMAddIncoming(g->cur_async_prev_val, incoming_values, incoming_blocks, 2);2150 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));
2151}2157}
21522158
2153static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *instruction) {2159static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *instruction) {
...@@ -2166,17 +2172,16 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns...@@ -2166,17 +2172,16 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
2166 // If the awaiter result pointer is non-null, we need to copy the result to there.2172 // If the awaiter result pointer is non-null, we need to copy the result to there.
2167 LLVMBasicBlockRef copy_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResult");2173 LLVMBasicBlockRef copy_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResult");
2168 LLVMBasicBlockRef copy_end_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResultEnd");2174 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, "");
2170 LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad(g->builder, awaiter_ret_ptr_ptr, "");2176 LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad(g->builder, awaiter_ret_ptr_ptr, "");
2171 LLVMValueRef zero_ptr = LLVMConstNull(LLVMTypeOf(awaiter_ret_ptr));2177 LLVMValueRef zero_ptr = LLVMConstNull(LLVMTypeOf(awaiter_ret_ptr));
2172 LLVMValueRef need_copy_bit = LLVMBuildICmp(g->builder, LLVMIntNE, awaiter_ret_ptr, zero_ptr, "");2178 LLVMValueRef need_copy_bit = LLVMBuildICmp(g->builder, LLVMIntNE, awaiter_ret_ptr, zero_ptr, "");
2173 LLVMBuildCondBr(g->builder, need_copy_bit, copy_block, copy_end_block);2179 LLVMBuildCondBr(g->builder, need_copy_bit, copy_block, copy_end_block);
21742180
2175 LLVMPositionBuilderAtEnd(g->builder, copy_block);2181 LLVMPositionBuilderAtEnd(g->builder, copy_block);
2176 LLVMValueRef ret_ptr = LLVMBuildLoad(g->builder, g->cur_ret_ptr_ptr, "");
2177 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);2182 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
2178 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, awaiter_ret_ptr, ptr_u8, "");2183 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, "");
2180 bool is_volatile = false;2185 bool is_volatile = false;
2181 uint32_t abi_align = get_abi_alignment(g, ret_type);2186 uint32_t abi_align = get_abi_alignment(g, ret_type);
2182 LLVMValueRef byte_count_val = LLVMConstInt(usize_type_ref, type_size(g, ret_type), false);2187 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,...@@ -3385,10 +3390,6 @@ static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutable *executable,
3385 if (!type_has_bits(instruction->base.value.type))3390 if (!type_has_bits(instruction->base.value.type))
3386 return nullptr;3391 return nullptr;
3387 src_assert(g->cur_ret_ptr != nullptr, instruction->base.source_node);3392 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 }
3392 return g->cur_ret_ptr;3393 return g->cur_ret_ptr;
3393}3394}
33943395
...@@ -3547,7 +3548,7 @@ static void render_async_spills(CodeGen *g) {...@@ -3547,7 +3548,7 @@ static void render_async_spills(CodeGen *g) {
3547 continue;3548 continue;
3548 }3549 }
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,
3551 buf_ptr(&var->name));3552 buf_ptr(&var->name));
3552 async_var_index += 1;3553 async_var_index += 1;
3553 if (var->decl_node) {3554 if (var->decl_node) {
...@@ -3578,7 +3579,7 @@ static void render_async_spills(CodeGen *g) {...@@ -3578,7 +3579,7 @@ static void render_async_spills(CodeGen *g) {
3578 continue;3579 continue;
3579 }3580 }
3580 }3581 }
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,
3582 instruction->name_hint);3583 instruction->name_hint);
3583 async_var_index += 1;3584 async_var_index += 1;
3584 }3585 }
...@@ -3697,7 +3698,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3697,7 +3698,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3697 // initialization.3698 // initialization.
3698 } else if (callee_is_async) {3699 } else if (callee_is_async) {
3699 frame_result_loc = ir_llvm_value(g, instruction->frame_result_loc);3700 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 pointer3701 awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, ""); // caller's own frame pointer
3701 if (ret_has_bits) {3702 if (ret_has_bits) {
3702 if (result_loc == nullptr) {3703 if (result_loc == nullptr) {
3703 // return type is a scalar, but we still need a pointer to it. Use the async fn frame.3704 // 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...@@ -4850,7 +4851,7 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutable *executable
4850}4851}
48514852
4852static LLVMValueRef ir_render_handle(CodeGen *g, IrExecutable *executable, IrInstructionFrameHandle *instruction) {4853static LLVMValueRef ir_render_handle(CodeGen *g, IrExecutable *executable, IrInstructionFrameHandle *instruction) {
4853 return g->cur_ret_ptr;4854 return g->cur_frame_ptr;
4854}4855}
48554856
4856static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp *instruction) {4857static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp *instruction) {
...@@ -5335,7 +5336,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst...@@ -5335,7 +5336,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst
5335 }5336 }
53365337
5337 // caller's own frame pointer5338 // 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, "");
5339 LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, coro_awaiter_index, "");5340 LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, coro_awaiter_index, "");
5340 LLVMValueRef prev_val = LLVMBuildAtomicRMW(g->builder, LLVMAtomicRMWBinOpXchg, awaiter_ptr, awaiter_init_val,5341 LLVMValueRef prev_val = LLVMBuildAtomicRMW(g->builder, LLVMAtomicRMWBinOpXchg, awaiter_ptr, awaiter_init_val,
5341 LLVMAtomicOrderingRelease, g->is_single_threaded);5342 LLVMAtomicOrderingRelease, g->is_single_threaded);
...@@ -6710,13 +6711,17 @@ static void do_code_gen(CodeGen *g) {...@@ -6710,13 +6711,17 @@ static void do_code_gen(CodeGen *g) {
67106711
6711 bool is_async = fn_is_async(fn_table_entry);6712 bool is_async = fn_is_async(fn_table_entry);
67126713
6713 if (want_sret || is_async) {6714 if (is_async) {
6714 g->cur_ret_ptr = LLVMGetParam(fn, 0);6715 g->cur_frame_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
6718 } else {6716 } 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 }
6720 }6725 }
67216726
6722 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry);6727 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) {...@@ -6870,21 +6875,22 @@ static void do_code_gen(CodeGen *g) {
68706875
6871 LLVMPositionBuilderAtEnd(g->builder, g->cur_preamble_llvm_block);6876 LLVMPositionBuilderAtEnd(g->builder, g->cur_preamble_llvm_block);
6872 render_async_spills(g);6877 render_async_spills(g);
6873 g->cur_async_awaiter_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_awaiter_index, "");6878 g->cur_async_awaiter_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, coro_awaiter_index, "");
6874 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_resume_index, "");6879 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, coro_resume_index, "");
6875 g->cur_async_resume_index_ptr = resume_index_ptr;6880 g->cur_async_resume_index_ptr = resume_index_ptr;
68766881
6877 if (type_has_bits(fn_type_id->return_type)) {6882 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, "");
6879 }6885 }
6880 if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {6886 if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
6881 uint32_t trace_field_index = frame_index_trace_arg(g, fn_type_id->return_type);6887 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, "");
6883 }6889 }
6884 uint32_t trace_field_index_stack = UINT32_MAX;6890 uint32_t trace_field_index_stack = UINT32_MAX;
6885 if (codegen_fn_has_err_ret_tracing_stack(g, fn_table_entry, true)) {6891 if (codegen_fn_has_err_ret_tracing_stack(g, fn_table_entry, true)) {
6886 trace_field_index_stack = frame_index_trace_stack(g, fn_type_id);6892 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,
6888 trace_field_index_stack, "");6894 trace_field_index_stack, "");
6889 }6895 }
68906896
...@@ -6898,9 +6904,9 @@ static void do_code_gen(CodeGen *g) {...@@ -6898,9 +6904,9 @@ static void do_code_gen(CodeGen *g) {
6898 g->cur_resume_block_count += 1;6904 g->cur_resume_block_count += 1;
6899 LLVMPositionBuilderAtEnd(g->builder, entry_block->llvm_block);6905 LLVMPositionBuilderAtEnd(g->builder, entry_block->llvm_block);
6900 if (trace_field_index_stack != UINT32_MAX) {6906 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,
6902 trace_field_index_stack, "");6908 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,
6904 trace_field_index_stack + 1, "");6910 trace_field_index_stack + 1, "");
69056911
6906 LLVMValueRef index_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 0, "");6912 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...@@ -1129,8 +1129,6 @@ static IrInstruction *ir_build_return_begin(IrBuilder *irb, Scope *scope, AstNod
1129 IrInstruction *operand)1129 IrInstruction *operand)
1130{1130{
1131 IrInstructionReturnBegin *return_instruction = ir_build_instruction<IrInstructionReturnBegin>(irb, scope, source_node);1131 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;
1134 return_instruction->operand = operand;1132 return_instruction->operand = operand;
11351133
1136 ir_ref_instruction(operand, irb->current_basic_block);1134 ir_ref_instruction(operand, irb->current_basic_block);
...@@ -3480,7 +3478,8 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3480,7 +3478,8 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
3480 return_value = ir_build_const_void(irb, scope, node);3478 return_value = ir_build_const_void(irb, scope, node);
3481 }3479 }
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
3485 size_t defer_counts[2];3484 size_t defer_counts[2];
3486 ir_count_defers(irb, scope, outer_scope, defer_counts);3485 ir_count_defers(irb, scope, outer_scope, defer_counts);
...@@ -3514,14 +3513,12 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3514,14 +3513,12 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
3514 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);3513 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
35153514
3516 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block);3515 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));
3518 IrInstruction *result = ir_build_return(irb, scope, node, return_value);3516 IrInstruction *result = ir_build_return(irb, scope, node, return_value);
3519 result_loc_ret->base.source_instruction = result;3517 result_loc_ret->base.source_instruction = result;
3520 return result;3518 return result;
3521 } else {3519 } else {
3522 // generate unconditional defers3520 // generate unconditional defers
3523 ir_gen_defers_for_block(irb, scope, outer_scope, false);3521 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));
3525 IrInstruction *result = ir_build_return(irb, scope, node, return_value);3522 IrInstruction *result = ir_build_return(irb, scope, node, return_value);
3526 result_loc_ret->base.source_instruction = result;3523 result_loc_ret->base.source_instruction = result;
3527 return result;3524 return result;
...@@ -3549,7 +3546,8 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3549,7 +3546,8 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
3549 ir_set_cursor_at_end_and_append_block(irb, return_block);3546 ir_set_cursor_at_end_and_append_block(irb, return_block);
3550 IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr);3547 IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr);
3551 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);3548 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);
3553 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) {3551 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) {
3554 ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1);3552 ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1);
3555 result_loc_ret->base.id = ResultLocIdReturn;3553 result_loc_ret->base.id = ResultLocIdReturn;
...@@ -3559,7 +3557,6 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3559,7 +3557,6 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
3559 if (irb->codegen->have_err_ret_tracing && !should_inline) {3557 if (irb->codegen->have_err_ret_tracing && !should_inline) {
3560 ir_build_save_err_ret_addr(irb, scope, node);3558 ir_build_save_err_ret_addr(irb, scope, node);
3561 }3559 }
3562 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val));
3563 IrInstruction *ret_inst = ir_build_return(irb, scope, node, err_val);3560 IrInstruction *ret_inst = ir_build_return(irb, scope, node, err_val);
3564 result_loc_ret->base.source_instruction = ret_inst;3561 result_loc_ret->base.source_instruction = ret_inst;
3565 }3562 }
...@@ -4972,7 +4969,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4972,7 +4969,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4972 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval, result_loc);4969 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval, result_loc);
4973 case BuiltinFnIdFrameHandle:4970 case BuiltinFnIdFrameHandle:
4974 if (!irb->exec->fn_entry) {4971 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"));
4976 return irb->codegen->invalid_instruction;4973 return irb->codegen->invalid_instruction;
4977 }4974 }
4978 return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval, result_loc);4975 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...@@ -8101,9 +8098,9 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
8101 return false;8098 return false;
81028099
8103 if (!instr_is_unreachable(result)) {8100 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
8106 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result));8101 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
8107 ir_mark_gen(ir_build_return(irb, scope, result->source_node, result));8104 ir_mark_gen(ir_build_return(irb, scope, result->source_node, result));
8108 }8105 }
81098106
...@@ -9789,6 +9786,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -9789,6 +9786,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
97899786
9790 ZigType *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type;9787 ZigType *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type;
9791 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;9788 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
9793 if (!resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) {9792 if (!resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) {
9794 return ira->codegen->builtin_types.entry_invalid;9793 return ira->codegen->builtin_types.entry_invalid;
...@@ -12614,6 +12613,14 @@ static IrInstruction *ir_analyze_instruction_return_begin(IrAnalyze *ira, IrInst...@@ -12614,6 +12613,14 @@ static IrInstruction *ir_analyze_instruction_return_begin(IrAnalyze *ira, IrInst
12614 if (type_is_invalid(operand->value.type))12613 if (type_is_invalid(operand->value.type))
12615 return ira->codegen->invalid_instruction;12614 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
12617 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type);12624 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type);
12618 if (type_is_invalid(casted_operand->value.type)) {12625 if (type_is_invalid(casted_operand->value.type)) {
12619 AstNode *source_node = ira->explicit_return_type_source_node;12626 AstNode *source_node = ira->explicit_return_type_source_node;
...@@ -12625,8 +12632,18 @@ static IrInstruction *ir_analyze_instruction_return_begin(IrAnalyze *ira, IrInst...@@ -12625,8 +12632,18 @@ static IrInstruction *ir_analyze_instruction_return_begin(IrAnalyze *ira, IrInst
12625 return ir_unreach_error(ira);12632 return ir_unreach_error(ira);
12626 }12633 }
1262712634
12628 return ir_build_return_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node,12635 if (casted_operand->value.special == ConstValSpecialRuntime &&
12629 casted_operand);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;
12630}12647}
1263112648
12632static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructionReturn *instruction) {12649static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructionReturn *instruction) {
...@@ -12642,21 +12659,8 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio...@@ -12642,21 +12659,8 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
12642 return ir_finish_anal(ira, result);12659 return ir_finish_anal(ira, result);
12643 }12660 }
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 }
12658 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,12662 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
12659 instruction->base.source_node, casted_operand);12663 instruction->base.source_node, operand);
12660 result->value.type = ira->codegen->builtin_types.entry_unreachable;12664 result->value.type = ira->codegen->builtin_types.entry_unreachable;
12661 return ir_finish_anal(ira, result);12665 return ir_finish_anal(ira, result);
12662}12666}
...@@ -14612,8 +14616,12 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -14612,8 +14616,12 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
14612 if ((err = type_resolve(ira->codegen, ira->explicit_return_type, ResolveStatusZeroBitsKnown))) {14616 if ((err = type_resolve(ira->codegen, ira->explicit_return_type, ResolveStatusZeroBitsKnown))) {
14613 return ira->codegen->invalid_instruction;14617 return ira->codegen->invalid_instruction;
14614 }14618 }
14615 if (!type_has_bits(ira->explicit_return_type) || !handle_is_ptr(ira->explicit_return_type))14619 if (!type_has_bits(ira->explicit_return_type) || !handle_is_ptr(ira->explicit_return_type)) {
14616 return nullptr;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
14618 ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false);14626 ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false);
14619 result_loc->written = true;14627 result_loc->written = true;
...@@ -24510,7 +24518,7 @@ static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstruction...@@ -24510,7 +24518,7 @@ static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstruction
24510 IrInstruction *result_loc;24518 IrInstruction *result_loc;
24511 if (type_has_bits(result_type)) {24519 if (type_has_bits(result_type)) {
24512 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,24520 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);
24514 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))24522 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))
24515 return result_loc;24523 return result_loc;
24516 } else {24524 } else {
test/stage1/behavior/coroutines.zig+34-34
...@@ -334,40 +334,40 @@ test "async fn with inferred error set" {...@@ -334,40 +334,40 @@ test "async fn with inferred error set" {
334 S.doTheTest();334 S.doTheTest();
335}335}
336336
337//test "error return trace across suspend points - early return" {337test "error return trace across suspend points - early return" {
338// const p = nonFailing();338 const p = nonFailing();
339// resume p;339 resume p;
340// const p2 = async printTrace(p);340 const p2 = async printTrace(p);
341//}341}
342//342
343//test "error return trace across suspend points - async return" {343test "error return trace across suspend points - async return" {
344// const p = nonFailing();344 const p = nonFailing();
345// const p2 = async printTrace(p);345 const p2 = async printTrace(p);
346// resume p;346 resume p;
347//}347}
348//348
349//fn nonFailing() (anyframe->anyerror!void) {349fn nonFailing() (anyframe->anyerror!void) {
350// const Static = struct {350 const Static = struct {
351// var frame: @Frame(suspendThenFail) = undefined;351 var frame: @Frame(suspendThenFail) = undefined;
352// };352 };
353// Static.frame = async suspendThenFail();353 Static.frame = async suspendThenFail();
354// return &Static.frame;354 return &Static.frame;
355//}355}
356//async fn suspendThenFail() anyerror!void {356async fn suspendThenFail() anyerror!void {
357// suspend;357 suspend;
358// return error.Fail;358 return error.Fail;
359//}359}
360//async fn printTrace(p: anyframe->(anyerror!void)) void {360async fn printTrace(p: anyframe->(anyerror!void)) void {
361// (await p) catch |e| {361 (await p) catch |e| {
362// std.testing.expect(e == error.Fail);362 std.testing.expect(e == error.Fail);
363// if (@errorReturnTrace()) |trace| {363 if (@errorReturnTrace()) |trace| {
364// expect(trace.index == 1);364 expect(trace.index == 1);
365// } else switch (builtin.mode) {365 } else switch (builtin.mode) {
366// .Debug, .ReleaseSafe => @panic("expected return trace"),366 .Debug, .ReleaseSafe => @panic("expected return trace"),
367// .ReleaseFast, .ReleaseSmall => {},367 .ReleaseFast, .ReleaseSmall => {},
368// }368 }
369// };369 };
370//}370}
371371
372test "break from suspend" {372test "break from suspend" {
373 var my_result: i32 = 1;373 var my_result: i32 = 1;