| ... | @@ -15537,6 +15537,26 @@ static bool ir_result_has_type(ResultLoc *result_loc) { | ... | @@ -15537,6 +15537,26 @@ static bool ir_result_has_type(ResultLoc *result_loc) { |
| 15537 | zig_unreachable(); | 15537 | zig_unreachable(); |
| 15538 | } | 15538 | } |
| 15539 | | 15539 | |
| | 15540 | static IrInstruction *ir_resolve_no_result_loc(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| | 15541 | ResultLoc *result_loc, ZigType *value_type, bool force_runtime, bool non_null_comptime) |
| | 15542 | { |
| | 15543 | Error err; |
| | 15544 | |
| | 15545 | IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, ""); |
| | 15546 | if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown))) |
| | 15547 | return ira->codegen->invalid_instruction; |
| | 15548 | alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, |
| | 15549 | PtrLenSingle, 0, 0, 0, false); |
| | 15550 | set_up_result_loc_for_inferred_comptime(&alloca_gen->base); |
| | 15551 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| | 15552 | if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) { |
| | 15553 | fn_entry->alloca_gen_list.append(alloca_gen); |
| | 15554 | } |
| | 15555 | result_loc->written = true; |
| | 15556 | result_loc->resolved_loc = &alloca_gen->base; |
| | 15557 | return result_loc->resolved_loc; |
| | 15558 | } |
| | 15559 | |
| 15540 | // when calling this function, at the callsite must check for result type noreturn and propagate it up | 15560 | // when calling this function, at the callsite must check for result type noreturn and propagate it up |
| 15541 | static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, | 15561 | static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 15542 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) | 15562 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) |
| ... | @@ -15559,19 +15579,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -15559,19 +15579,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 15559 | return nullptr; | 15579 | return nullptr; |
| 15560 | } | 15580 | } |
| 15561 | // need to return a result location and don't have one. use a stack allocation | 15581 | // need to return a result location and don't have one. use a stack allocation |
| 15562 | IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, ""); | 15582 | return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, |
| 15563 | if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown))) | 15583 | force_runtime, non_null_comptime); |
| 15564 | return ira->codegen->invalid_instruction; | | |
| 15565 | alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, | | |
| 15566 | PtrLenSingle, 0, 0, 0, false); | | |
| 15567 | set_up_result_loc_for_inferred_comptime(&alloca_gen->base); | | |
| 15568 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); | | |
| 15569 | if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) { | | |
| 15570 | fn_entry->alloca_gen_list.append(alloca_gen); | | |
| 15571 | } | | |
| 15572 | result_loc->written = true; | | |
| 15573 | result_loc->resolved_loc = &alloca_gen->base; | | |
| 15574 | return result_loc->resolved_loc; | | |
| 15575 | } | 15584 | } |
| 15576 | case ResultLocIdVar: { | 15585 | case ResultLocIdVar: { |
| 15577 | ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); | 15586 | ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); |
| ... | @@ -15710,6 +15719,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -15710,6 +15719,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 15710 | return result_loc->resolved_loc; | 15719 | return result_loc->resolved_loc; |
| 15711 | } | 15720 | } |
| 15712 | case ResultLocIdCast: { | 15721 | case ResultLocIdCast: { |
| | 15722 | if (!non_null_comptime && value != nullptr && value->value.special != ConstValSpecialRuntime) |
| | 15723 | return nullptr; |
| 15713 | ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); | 15724 | ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); |
| 15714 | ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); | 15725 | ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); |
| 15715 | if (type_is_invalid(dest_type)) | 15726 | if (type_is_invalid(dest_type)) |
| ... | @@ -15720,9 +15731,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -15720,9 +15731,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 15720 | if (const_cast_result.id == ConstCastResultIdInvalid) | 15731 | if (const_cast_result.id == ConstCastResultIdInvalid) |
| 15721 | return ira->codegen->invalid_instruction; | 15732 | return ira->codegen->invalid_instruction; |
| 15722 | if (const_cast_result.id != ConstCastResultIdOk) { | 15733 | if (const_cast_result.id != ConstCastResultIdOk) { |
| 15723 | // We will not be able to provide a result location for this value. Allow the | 15734 | // We will not be able to provide a result location for this value. Create |
| 15724 | // code to create a new result location and then type coerce to the old one. | 15735 | // a new result location. |
| 15725 | return nullptr; | 15736 | return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, |
| | 15737 | force_runtime, non_null_comptime); |
| 15726 | } | 15738 | } |
| 15727 | | 15739 | |
| 15728 | // In this case we can pointer cast the result location. | 15740 | // In this case we can pointer cast the result location. |
| ... | @@ -15755,6 +15767,9 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -15755,6 +15767,9 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 15755 | if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { | 15767 | if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { |
| 15756 | return ira->codegen->invalid_instruction; | 15768 | return ira->codegen->invalid_instruction; |
| 15757 | } | 15769 | } |
| | 15770 | if (!type_has_bits(value_type)) { |
| | 15771 | parent_ptr_align = 0; |
| | 15772 | } |
| 15758 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, | 15773 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, |
| 15759 | parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, | 15774 | parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, |
| 15760 | parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); | 15775 | parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); |