| ... | ... | @@ -187,6 +187,8 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_ |
| 187 | 187 | ZigType *dest_type); |
| 188 | 188 | static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 189 | 189 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value); |
| 190 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 191 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); |
| 190 | 192 | |
| 191 | 193 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 192 | 194 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | ... | @@ -1095,13 +1097,15 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *so |
| 1095 | 1097 | return &cond_br_instruction->base; |
| 1096 | 1098 | } |
| 1097 | 1099 | |
| 1098 | | static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *return_value) { |
| 1100 | static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1101 | IrInstruction *return_value) |
| 1102 | { |
| 1099 | 1103 | IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); |
| 1100 | 1104 | return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; |
| 1101 | 1105 | return_instruction->base.value.special = ConstValSpecialStatic; |
| 1102 | 1106 | return_instruction->value = return_value; |
| 1103 | 1107 | |
| 1104 | | ir_ref_instruction(return_value, irb->current_basic_block); |
| 1108 | if (return_value != nullptr) ir_ref_instruction(return_value, irb->current_basic_block); |
| 1105 | 1109 | |
| 1106 | 1110 | return &return_instruction->base; |
| 1107 | 1111 | } |
| ... | ... | @@ -1756,11 +1760,12 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod |
| 1756 | 1760 | } |
| 1757 | 1761 | |
| 1758 | 1762 | static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1759 | | IrInstruction *base_ptr, bool safety_check_on) |
| 1763 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 1760 | 1764 | { |
| 1761 | 1765 | IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node); |
| 1762 | 1766 | instruction->base_ptr = base_ptr; |
| 1763 | 1767 | instruction->safety_check_on = safety_check_on; |
| 1768 | instruction->initializing = initializing; |
| 1764 | 1769 | |
| 1765 | 1770 | ir_ref_instruction(base_ptr, irb->current_basic_block); |
| 1766 | 1771 | |
| ... | ... | @@ -3918,7 +3923,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3918 | 3923 | ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); |
| 3919 | 3924 | |
| 3920 | 3925 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 3921 | | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false); |
| 3926 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false); |
| 3922 | 3927 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); |
| 3923 | 3928 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers[1].base); |
| 3924 | 3929 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| ... | ... | @@ -6009,7 +6014,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 6009 | 6014 | ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, end_block, result_loc); |
| 6010 | 6015 | |
| 6011 | 6016 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 6012 | | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false); |
| 6017 | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false, false); |
| 6013 | 6018 | IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? |
| 6014 | 6019 | ir_build_ref(irb, child_scope, symbol_node, payload_ptr, true, false) : payload_ptr; |
| 6015 | 6020 | ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, var_ptr); |
| ... | ... | @@ -6609,7 +6614,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN |
| 6609 | 6614 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6610 | 6615 | var_symbol, is_const, is_const, is_shadowable, is_comptime); |
| 6611 | 6616 | |
| 6612 | | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false); |
| 6617 | IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false); |
| 6613 | 6618 | IrInstruction *var_ptr = var_is_ptr ? ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; |
| 6614 | 6619 | ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); |
| 6615 | 6620 | var_scope = var->child_scope; |
| ... | ... | @@ -8094,7 +8099,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 8094 | 8099 | if (maybe_ptr == irb->codegen->invalid_instruction) |
| 8095 | 8100 | return irb->codegen->invalid_instruction; |
| 8096 | 8101 | |
| 8097 | | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true); |
| 8102 | IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true, false); |
| 8098 | 8103 | if (lval == LValPtr) |
| 8099 | 8104 | return unwrapped_ptr; |
| 8100 | 8105 | |
| ... | ... | @@ -8375,7 +8380,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8375 | 8380 | // a register or local variable which does not get spilled into the frame, |
| 8376 | 8381 | // otherwise llvm tries to access memory inside the destroyed frame. |
| 8377 | 8382 | IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, |
| 8378 | | irb->exec->await_handle_var_ptr, false); |
| 8383 | irb->exec->await_handle_var_ptr, false, false); |
| 8379 | 8384 | IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); |
| 8380 | 8385 | ir_build_br(irb, scope, node, check_free_block, const_bool_false); |
| 8381 | 8386 | |
| ... | ... | @@ -12871,6 +12876,14 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio |
| 12871 | 12876 | if (type_is_invalid(value->value.type)) |
| 12872 | 12877 | return ir_unreach_error(ira); |
| 12873 | 12878 | |
| 12879 | if (!instr_is_comptime(value) && handle_is_ptr(ira->explicit_return_type)) { |
| 12880 | // result location mechanism took care of it. |
| 12881 | IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, |
| 12882 | instruction->base.source_node, nullptr); |
| 12883 | result->value.type = ira->codegen->builtin_types.entry_unreachable; |
| 12884 | return ir_finish_anal(ira, result); |
| 12885 | } |
| 12886 | |
| 12874 | 12887 | IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type); |
| 12875 | 12888 | if (type_is_invalid(casted_value->value.type)) { |
| 12876 | 12889 | AstNode *source_node = ira->explicit_return_type_source_node; |
| ... | ... | @@ -14925,10 +14938,17 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns |
| 14925 | 14938 | } |
| 14926 | 14939 | |
| 14927 | 14940 | static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) { |
| 14928 | | ZigType *ty = ir_resolve_type(ira, instruction->ty->child); |
| 14929 | | if (type_is_invalid(ty)) |
| 14941 | ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); |
| 14942 | if (type_is_invalid(implicit_elem_type)) |
| 14930 | 14943 | return ira->codegen->invalid_instruction; |
| 14931 | | return ir_resolve_result(ira, &instruction->base, instruction->result_loc, ty, nullptr); |
| 14944 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 14945 | implicit_elem_type, nullptr); |
| 14946 | ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base); |
| 14947 | ZigType *actual_elem_type = result_loc->value.type->data.pointer.child_type; |
| 14948 | if (actual_elem_type->id == ZigTypeIdOptional && implicit_elem_type->id != ZigTypeIdOptional) { |
| 14949 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, result_loc, false, true); |
| 14950 | } |
| 14951 | return result_loc; |
| 14932 | 14952 | } |
| 14933 | 14953 | |
| 14934 | 14954 | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry, |
| ... | ... | @@ -17876,7 +17896,7 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns |
| 17876 | 17896 | } |
| 17877 | 17897 | |
| 17878 | 17898 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 17879 | | IrInstruction *base_ptr, bool safety_check_on) |
| 17899 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 17880 | 17900 | { |
| 17881 | 17901 | ZigType *ptr_type = base_ptr->value.type; |
| 17882 | 17902 | assert(ptr_type->id == ZigTypeIdPointer); |
| ... | ... | @@ -17948,7 +17968,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 17948 | 17968 | } |
| 17949 | 17969 | |
| 17950 | 17970 | IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, |
| 17951 | | source_instr->source_node, base_ptr, safety_check_on); |
| 17971 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 17952 | 17972 | result->value.type = result_type; |
| 17953 | 17973 | return result; |
| 17954 | 17974 | } |
| ... | ... | @@ -17960,7 +17980,8 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, |
| 17960 | 17980 | if (type_is_invalid(base_ptr->value.type)) |
| 17961 | 17981 | return ira->codegen->invalid_instruction; |
| 17962 | 17982 | |
| 17963 | | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on); |
| 17983 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, |
| 17984 | instruction->safety_check_on, false); |
| 17964 | 17985 | } |
| 17965 | 17986 | |
| 17966 | 17987 | static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { |