| ... | ... | @@ -185,7 +185,8 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc |
| 185 | 185 | ZigType *ptr_type); |
| 186 | 186 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 187 | 187 | ZigType *dest_type); |
| 188 | | static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, ZigType *value_type, IrInstruction *value); |
| 188 | static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 189 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value); |
| 189 | 190 | |
| 190 | 191 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 191 | 192 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | ... | @@ -1376,11 +1377,8 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s |
| 1376 | 1377 | static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, |
| 1377 | 1378 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1378 | 1379 | FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack, |
| 1379 | | ResultLoc *result_loc, ZigType *return_type) |
| 1380 | IrInstruction *result_loc, ZigType *return_type) |
| 1380 | 1381 | { |
| 1381 | | // must be resolved before building the call instruction |
| 1382 | | IrInstruction *resolved_result_loc = ir_resolve_result(ira, result_loc, return_type, nullptr); |
| 1383 | | |
| 1384 | 1382 | IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, |
| 1385 | 1383 | source_instruction->scope, source_instruction->source_node); |
| 1386 | 1384 | call_instruction->base.value.type = return_type; |
| ... | ... | @@ -1392,14 +1390,14 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in |
| 1392 | 1390 | call_instruction->is_async = is_async; |
| 1393 | 1391 | call_instruction->async_allocator = async_allocator; |
| 1394 | 1392 | call_instruction->new_stack = new_stack; |
| 1395 | | call_instruction->result_loc = resolved_result_loc; |
| 1393 | call_instruction->result_loc = result_loc; |
| 1396 | 1394 | |
| 1397 | 1395 | if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block); |
| 1398 | 1396 | for (size_t i = 0; i < arg_count; i += 1) |
| 1399 | 1397 | ir_ref_instruction(args[i], ira->new_irb.current_basic_block); |
| 1400 | 1398 | if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block); |
| 1401 | 1399 | if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block); |
| 1402 | | if (call_instruction->result_loc != nullptr) ir_ref_instruction(call_instruction->result_loc, ira->new_irb.current_basic_block); |
| 1400 | if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); |
| 1403 | 1401 | |
| 1404 | 1402 | return &call_instruction->base; |
| 1405 | 1403 | } |
| ... | ... | @@ -5366,7 +5364,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5366 | 5364 | incoming_blocks[1] = after_else_block; |
| 5367 | 5365 | |
| 5368 | 5366 | IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 5369 | | return ir_lval_wrap(irb, scope, phi, lval, result_loc); |
| 5367 | return ir_expr_wrap(irb, scope, phi, result_loc); |
| 5370 | 5368 | } |
| 5371 | 5369 | |
| 5372 | 5370 | static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { |
| ... | ... | @@ -6558,10 +6556,11 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit |
| 6558 | 6556 | return true; |
| 6559 | 6557 | } |
| 6560 | 6558 | |
| 6561 | | static void next_peer_block(ZigList<ResultLocPeer> *list, IrBasicBlock *next_bb) { |
| 6562 | | if (list->length >= 2) { |
| 6563 | | list->at(list->length - 2).next_bb = next_bb; |
| 6559 | static void next_peer_block(ResultLocPeerParent *peer_parent, IrBasicBlock *next_bb) { |
| 6560 | if (peer_parent->peer_count > 0) { |
| 6561 | peer_parent->peers[peer_parent->peer_count - 1].next_bb = next_bb; |
| 6564 | 6562 | } |
| 6563 | peer_parent->peer_count += 1; |
| 6565 | 6564 | } |
| 6566 | 6565 | |
| 6567 | 6566 | static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| ... | ... | @@ -6600,8 +6599,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6600 | 6599 | ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); |
| 6601 | 6600 | peer_parent->base.id = ResultLocIdPeerParent; |
| 6602 | 6601 | peer_parent->parent = result_loc; |
| 6603 | | |
| 6604 | | ZigList<ResultLocPeer> peer_result_locs = {}; |
| 6602 | peer_parent->peers = allocate<ResultLocPeer>(prong_count); |
| 6603 | peer_parent->peer_count = 0; |
| 6605 | 6604 | |
| 6606 | 6605 | // First do the else and the ranges |
| 6607 | 6606 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); |
| ... | ... | @@ -6611,7 +6610,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6611 | 6610 | AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); |
| 6612 | 6611 | size_t prong_item_count = prong_node->data.switch_prong.items.length; |
| 6613 | 6612 | if (prong_item_count == 0) { |
| 6614 | | ResultLocPeer *this_peer_result_loc = peer_result_locs.add_one(); |
| 6613 | ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count]; |
| 6615 | 6614 | this_peer_result_loc->base.id = ResultLocIdPeer; |
| 6616 | 6615 | this_peer_result_loc->parent = peer_parent; |
| 6617 | 6616 | if (else_prong) { |
| ... | ... | @@ -6624,7 +6623,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6624 | 6623 | else_prong = prong_node; |
| 6625 | 6624 | |
| 6626 | 6625 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 6627 | | next_peer_block(&peer_result_locs, else_block); |
| 6626 | next_peer_block(peer_parent, else_block); |
| 6628 | 6627 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6629 | 6628 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6630 | 6629 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, |
| ... | ... | @@ -6634,7 +6633,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6634 | 6633 | } |
| 6635 | 6634 | ir_set_cursor_at_end(irb, prev_block); |
| 6636 | 6635 | } else if (prong_node->data.switch_prong.any_items_are_range) { |
| 6637 | | ResultLocPeer *this_peer_result_loc = peer_result_locs.add_one(); |
| 6636 | ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count]; |
| 6638 | 6637 | this_peer_result_loc->base.id = ResultLocIdPeer; |
| 6639 | 6638 | this_peer_result_loc->parent = peer_parent; |
| 6640 | 6639 | |
| ... | ... | @@ -6697,7 +6696,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6697 | 6696 | ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, |
| 6698 | 6697 | range_block_no, is_comptime)); |
| 6699 | 6698 | |
| 6700 | | next_peer_block(&peer_result_locs, range_block_yes); |
| 6699 | next_peer_block(peer_parent, range_block_yes); |
| 6701 | 6700 | ir_set_cursor_at_end_and_append_block(irb, range_block_yes); |
| 6702 | 6701 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6703 | 6702 | is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, |
| ... | ... | @@ -6719,7 +6718,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6719 | 6718 | if (prong_node->data.switch_prong.any_items_are_range) |
| 6720 | 6719 | continue; |
| 6721 | 6720 | |
| 6722 | | ResultLocPeer *this_peer_result_loc = peer_result_locs.add_one(); |
| 6721 | ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count]; |
| 6723 | 6722 | this_peer_result_loc->base.id = ResultLocIdPeer; |
| 6724 | 6723 | this_peer_result_loc->parent = peer_parent; |
| 6725 | 6724 | |
| ... | ... | @@ -6746,7 +6745,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6746 | 6745 | } |
| 6747 | 6746 | |
| 6748 | 6747 | IrBasicBlock *prev_block = irb->current_basic_block; |
| 6749 | | next_peer_block(&peer_result_locs, prong_block); |
| 6748 | next_peer_block(peer_parent, prong_block); |
| 6750 | 6749 | ir_set_cursor_at_end_and_append_block(irb, prong_block); |
| 6751 | 6750 | if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, |
| 6752 | 6751 | is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, |
| ... | ... | @@ -6773,22 +6772,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6773 | 6772 | } |
| 6774 | 6773 | br_instruction = &switch_br->base; |
| 6775 | 6774 | } |
| 6776 | | for (size_t i = 0; i < peer_result_locs.length; i += 1) { |
| 6777 | | peer_result_locs.at(i).base.source_instruction = br_instruction; |
| 6775 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { |
| 6776 | peer_parent->peers[i].base.source_instruction = br_instruction; |
| 6778 | 6777 | } |
| 6779 | 6778 | peer_parent->base.source_instruction = br_instruction; |
| 6780 | | peer_parent->peer_count = peer_result_locs.length; |
| 6781 | | peer_parent->peers = peer_result_locs.items; |
| 6782 | 6779 | |
| 6783 | 6780 | if (!else_prong) { |
| 6784 | | if (peer_result_locs.length != 0) { |
| 6785 | | peer_result_locs.last().next_bb = else_block; |
| 6781 | if (peer_parent->peer_count != 0) { |
| 6782 | peer_parent->peers[peer_parent->peer_count - 1].next_bb = else_block; |
| 6786 | 6783 | } |
| 6787 | 6784 | ir_set_cursor_at_end_and_append_block(irb, else_block); |
| 6788 | 6785 | ir_build_unreachable(irb, scope, node); |
| 6789 | 6786 | } else { |
| 6790 | | if (peer_result_locs.length != 0) { |
| 6791 | | peer_result_locs.last().next_bb = end_block; |
| 6787 | if (peer_parent->peer_count != 0) { |
| 6788 | peer_parent->peers[peer_parent->peer_count - 1].next_bb = end_block; |
| 6792 | 6789 | } |
| 6793 | 6790 | } |
| 6794 | 6791 | |
| ... | ... | @@ -14400,12 +14397,12 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, ResultLoc *result_lo |
| 14400 | 14397 | |
| 14401 | 14398 | // give nullptr for value to resolve it at runtime |
| 14402 | 14399 | // returns a result location, or nullptr if the result location was already taken care of |
| 14403 | | static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, ZigType *value_type, |
| 14404 | | IrInstruction *value) |
| 14400 | // when calling this function, at the callsite must check for result type noreturn and propagate it up |
| 14401 | static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 14402 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value) |
| 14405 | 14403 | { |
| 14406 | | if (result_loc->implicit_elem_type != nullptr) { |
| 14407 | | // already resolved |
| 14408 | | return nullptr; |
| 14404 | if (result_loc->resolved_loc != nullptr) { |
| 14405 | return result_loc->resolved_loc; |
| 14409 | 14406 | } |
| 14410 | 14407 | result_loc->gen_instruction = value; |
| 14411 | 14408 | result_loc->implicit_elem_type = value_type; |
| ... | ... | @@ -14420,12 +14417,12 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, Z |
| 14420 | 14417 | assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc); |
| 14421 | 14418 | IrInstructionAllocaSrc *alloca_src = |
| 14422 | 14419 | reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); |
| 14420 | bool force_comptime; |
| 14421 | if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) |
| 14422 | return ira->codegen->invalid_instruction; |
| 14423 | bool is_comptime = force_comptime || (value != nullptr && |
| 14424 | value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); |
| 14423 | 14425 | if (alloca_src->base.child == nullptr) { |
| 14424 | | bool force_comptime; |
| 14425 | | if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) |
| 14426 | | return ira->codegen->invalid_instruction; |
| 14427 | | bool is_comptime = force_comptime || (value != nullptr && |
| 14428 | | value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); |
| 14429 | 14426 | uint32_t align = 0; |
| 14430 | 14427 | if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, &align)) { |
| 14431 | 14428 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -14441,18 +14438,67 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, Z |
| 14441 | 14438 | alloca_src->name_hint, force_comptime); |
| 14442 | 14439 | } |
| 14443 | 14440 | alloca_src->base.child = alloca_gen; |
| 14444 | | return is_comptime ? nullptr : alloca_src->base.child; |
| 14445 | 14441 | } |
| 14446 | | return nullptr; |
| 14442 | result_loc->written = true; |
| 14443 | result_loc->resolved_loc = is_comptime ? nullptr : alloca_src->base.child; |
| 14444 | return result_loc->resolved_loc; |
| 14447 | 14445 | } |
| 14448 | 14446 | case ResultLocIdReturn: { |
| 14449 | 14447 | bool is_comptime = value != nullptr && value->value.special != ConstValSpecialRuntime; |
| 14450 | 14448 | if (is_comptime) return nullptr; |
| 14451 | 14449 | ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false); |
| 14452 | | return ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type); |
| 14450 | result_loc->written = true; |
| 14451 | result_loc->resolved_loc = ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type); |
| 14452 | return result_loc->resolved_loc; |
| 14453 | } |
| 14454 | case ResultLocIdPeer: { |
| 14455 | ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(result_loc); |
| 14456 | ResultLocPeerParent *peer_parent = result_peer->parent; |
| 14457 | |
| 14458 | if (ira->const_predecessor_bb) |
| 14459 | return nullptr; |
| 14460 | |
| 14461 | if (peer_parent->resolved_type == nullptr) { |
| 14462 | IrInstruction *suspended_inst = ira_suspend(ira, suspend_source_instr, |
| 14463 | result_peer->next_bb, &result_peer->suspend_pos); |
| 14464 | bool last_one = (result_peer == &peer_parent->peers[peer_parent->peer_count - 1]); |
| 14465 | if (!last_one) { |
| 14466 | return suspended_inst; |
| 14467 | } |
| 14468 | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count); |
| 14469 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { |
| 14470 | ResultLocPeer *this_peer = &peer_parent->peers[i]; |
| 14471 | ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1]; |
| 14472 | |
| 14473 | IrInstruction *gen_instruction = this_peer->base.gen_instruction; |
| 14474 | if (gen_instruction == nullptr) { |
| 14475 | instructions[i] = ir_const(ira, this_peer->base.source_instruction, |
| 14476 | this_peer->base.implicit_elem_type); |
| 14477 | instructions[i]->value.special = ConstValSpecialRuntime; |
| 14478 | } else { |
| 14479 | instructions[i] = gen_instruction; |
| 14480 | } |
| 14481 | if (opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) { |
| 14482 | ira->resume_stack.append(opposite_peer->suspend_pos); |
| 14483 | } |
| 14484 | } |
| 14485 | ZigType *expected_type = ir_result_loc_expected_type(ira, peer_parent->parent); |
| 14486 | peer_parent->resolved_type = ir_resolve_peer_types(ira, |
| 14487 | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| 14488 | peer_parent->peer_count); |
| 14489 | return ira_resume(ira); |
| 14490 | } |
| 14491 | |
| 14492 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| 14493 | peer_parent->resolved_type, nullptr); |
| 14494 | if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || |
| 14495 | parent_result_loc->value.type->id == ZigTypeIdUnreachable) |
| 14496 | { |
| 14497 | return parent_result_loc; |
| 14498 | } |
| 14499 | result_loc->resolved_loc = parent_result_loc; |
| 14500 | return result_loc->resolved_loc; |
| 14453 | 14501 | } |
| 14454 | | case ResultLocIdPeer: |
| 14455 | | return nullptr; |
| 14456 | 14502 | } |
| 14457 | 14503 | zig_unreachable(); |
| 14458 | 14504 | } |
| ... | ... | @@ -14504,7 +14550,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc |
| 14504 | 14550 | ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); |
| 14505 | 14551 | |
| 14506 | 14552 | return ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count, |
| 14507 | | casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, call_instruction->result_loc, |
| 14553 | casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, nullptr, |
| 14508 | 14554 | async_return_type); |
| 14509 | 14555 | } |
| 14510 | 14556 | |
| ... | ... | @@ -15246,6 +15292,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15246 | 15292 | } |
| 15247 | 15293 | |
| 15248 | 15294 | FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; |
| 15295 | IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| 15296 | impl_fn_type_id->return_type, nullptr); |
| 15297 | if (result_loc != nullptr && |
| 15298 | (type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable)) |
| 15299 | { |
| 15300 | return result_loc; |
| 15301 | } |
| 15302 | |
| 15249 | 15303 | if (fn_type_can_fail(impl_fn_type_id)) { |
| 15250 | 15304 | parent_fn_entry->calls_or_awaits_errorable_fn = true; |
| 15251 | 15305 | } |
| ... | ... | @@ -15257,10 +15311,11 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15257 | 15311 | return ir_finish_anal(ira, result); |
| 15258 | 15312 | } |
| 15259 | 15313 | |
| 15314 | call_instruction->result_loc->written = true; |
| 15260 | 15315 | assert(async_allocator_inst == nullptr); |
| 15261 | 15316 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, |
| 15262 | 15317 | impl_fn, nullptr, impl_param_count, casted_args, fn_inline, |
| 15263 | | call_instruction->is_async, nullptr, casted_new_stack, call_instruction->result_loc, |
| 15318 | call_instruction->is_async, nullptr, casted_new_stack, result_loc, |
| 15264 | 15319 | impl_fn_type_id->return_type); |
| 15265 | 15320 | |
| 15266 | 15321 | return ir_finish_anal(ira, new_call_instruction); |
| ... | ... | @@ -15355,9 +15410,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15355 | 15410 | return ira->codegen->invalid_instruction; |
| 15356 | 15411 | } |
| 15357 | 15412 | |
| 15413 | IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
| 15414 | return_type, nullptr); |
| 15415 | if (result_loc != nullptr && |
| 15416 | (type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable)) |
| 15417 | { |
| 15418 | return result_loc; |
| 15419 | } |
| 15420 | |
| 15421 | call_instruction->result_loc->written = true; |
| 15358 | 15422 | IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, |
| 15359 | 15423 | call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack, |
| 15360 | | call_instruction->result_loc, return_type); |
| 15424 | result_loc, return_type); |
| 15361 | 15425 | return ir_finish_anal(ira, new_call_instruction); |
| 15362 | 15426 | } |
| 15363 | 15427 | |
| ... | ... | @@ -23619,35 +23683,19 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct |
| 23619 | 23683 | if (type_is_invalid(value->value.type)) |
| 23620 | 23684 | return ira->codegen->invalid_instruction; |
| 23621 | 23685 | |
| 23622 | | if (instruction->result_loc->id == ResultLocIdPeer) { |
| 23623 | | ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(instruction->result_loc); |
| 23624 | | ResultLocPeerParent *peer_parent = result_peer->parent; |
| 23686 | if (!instruction->result_loc->written) { |
| 23687 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 23688 | value->value.type, value); |
| 23689 | if (result_loc != nullptr) { |
| 23690 | if (type_is_invalid(result_loc->value.type)) |
| 23691 | return ira->codegen->invalid_instruction; |
| 23692 | if (result_loc->value.type->id == ZigTypeIdUnreachable) |
| 23693 | return result_loc; |
| 23625 | 23694 | |
| 23626 | | if (peer_parent->resolved_type == nullptr && !ira->const_predecessor_bb) { |
| 23627 | | instruction->result_loc->implicit_elem_type = value->value.type; |
| 23628 | | instruction->result_loc->gen_instruction = value; |
| 23629 | | IrInstruction *suspended_inst = ira_suspend(ira, &instruction->base, result_peer->next_bb, |
| 23630 | | &result_peer->suspend_pos); |
| 23631 | | bool last_one = (result_peer == &peer_parent->peers[peer_parent->peer_count - 1]); |
| 23632 | | if (!last_one) { |
| 23633 | | return suspended_inst; |
| 23634 | | } |
| 23635 | | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count); |
| 23636 | | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { |
| 23637 | | instructions[i] = peer_parent->peers[i].base.gen_instruction; |
| 23638 | | ira->resume_stack.append(peer_parent->peers[peer_parent->peer_count - i - 1].suspend_pos); |
| 23639 | | } |
| 23640 | | ZigType *expected_type = ir_result_loc_expected_type(ira, peer_parent->parent); |
| 23641 | | peer_parent->resolved_type = ir_resolve_peer_types(ira, |
| 23642 | | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| 23643 | | peer_parent->peer_count); |
| 23644 | | return ira_resume(ira); |
| 23695 | instruction->result_loc->written = true; |
| 23696 | ir_analyze_store_ptr(ira, &instruction->base, result_loc, value); |
| 23645 | 23697 | } |
| 23646 | 23698 | } |
| 23647 | | IrInstruction *result_loc = ir_resolve_result(ira, instruction->result_loc, value->value.type, value); |
| 23648 | | if (result_loc != nullptr && !type_is_invalid(result_loc->value.type)) { |
| 23649 | | ir_analyze_store_ptr(ira, &instruction->base, result_loc, value); |
| 23650 | | } |
| 23651 | 23699 | |
| 23652 | 23700 | return ir_const_void(ira, &instruction->base); |
| 23653 | 23701 | } |