| ... | ... | @@ -788,8 +788,10 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) { |
| 788 | 788 | |
| 789 | 789 | TypeTableEntry *src_return_type = fn_type->data.fn.fn_type_id.return_type; |
| 790 | 790 | |
| 791 | bool ret_has_bits = type_has_bits(src_return_type); |
| 792 | |
| 791 | 793 | int fn_call_param_count = node->data.fn_call_expr.params.length; |
| 792 | | bool first_arg_ret = handle_is_ptr(src_return_type); |
| 794 | bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type); |
| 793 | 795 | int actual_param_count = fn_call_param_count + (struct_type ? 1 : 0) + (first_arg_ret ? 1 : 0); |
| 794 | 796 | bool is_var_args = fn_type->data.fn.fn_type_id.is_var_args; |
| 795 | 797 | |
| ... | ... | @@ -824,10 +826,10 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) { |
| 824 | 826 | |
| 825 | 827 | if (src_return_type->id == TypeTableEntryIdUnreachable) { |
| 826 | 828 | return LLVMBuildUnreachable(g->builder); |
| 829 | } else if (!ret_has_bits) { |
| 830 | return nullptr; |
| 827 | 831 | } else if (first_arg_ret) { |
| 828 | 832 | return node->data.fn_call_expr.tmp_ptr; |
| 829 | | } else if (!type_has_bits(src_return_type)) { |
| 830 | | return nullptr; |
| 831 | 833 | } else { |
| 832 | 834 | return result; |
| 833 | 835 | } |
| ... | ... | @@ -1568,6 +1570,9 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b |
| 1568 | 1570 | LLVMValueRef target_ref, LLVMValueRef value, |
| 1569 | 1571 | TypeTableEntry *op1_type, TypeTableEntry *op2_type) |
| 1570 | 1572 | { |
| 1573 | if (!type_has_bits(op1_type)) { |
| 1574 | return nullptr; |
| 1575 | } |
| 1571 | 1576 | if (handle_is_ptr(op1_type)) { |
| 1572 | 1577 | assert(op1_type == op2_type); |
| 1573 | 1578 | assert(bin_op == BinOpTypeAssign); |
| ... | ... | @@ -1584,7 +1589,8 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b |
| 1584 | 1589 | } |
| 1585 | 1590 | |
| 1586 | 1591 | add_debug_source_node(g, source_node); |
| 1587 | | return LLVMBuildStore(g->builder, value, target_ref); |
| 1592 | LLVMBuildStore(g->builder, value, target_ref); |
| 1593 | return nullptr; |
| 1588 | 1594 | } |
| 1589 | 1595 | |
| 1590 | 1596 | static LLVMValueRef gen_assign_expr(CodeGen *g, AstNode *node) { |
| ... | ... | @@ -1600,11 +1606,8 @@ static LLVMValueRef gen_assign_expr(CodeGen *g, AstNode *node) { |
| 1600 | 1606 | |
| 1601 | 1607 | LLVMValueRef value = gen_expr(g, node->data.bin_op_expr.op2); |
| 1602 | 1608 | |
| 1603 | | if (!type_has_bits(op1_type)) { |
| 1604 | | return nullptr; |
| 1605 | | } |
| 1606 | | |
| 1607 | | return gen_assign_raw(g, node, node->data.bin_op_expr.bin_op, target_ref, value, op1_type, op2_type); |
| 1609 | gen_assign_raw(g, node, node->data.bin_op_expr.bin_op, target_ref, value, op1_type, op2_type); |
| 1610 | return nullptr; |
| 1608 | 1611 | } |
| 1609 | 1612 | |
| 1610 | 1613 | static LLVMValueRef gen_unwrap_maybe(CodeGen *g, AstNode *node, LLVMValueRef maybe_struct_ref) { |
| ... | ... | @@ -1846,11 +1849,12 @@ static LLVMValueRef gen_return(CodeGen *g, AstNode *source_node, LLVMValueRef va |
| 1846 | 1849 | assert(g->cur_ret_ptr); |
| 1847 | 1850 | gen_assign_raw(g, source_node, BinOpTypeAssign, g->cur_ret_ptr, value, return_type, return_type); |
| 1848 | 1851 | add_debug_source_node(g, source_node); |
| 1849 | | return LLVMBuildRetVoid(g->builder); |
| 1852 | LLVMBuildRetVoid(g->builder); |
| 1850 | 1853 | } else { |
| 1851 | 1854 | add_debug_source_node(g, source_node); |
| 1852 | | return LLVMBuildRet(g->builder, value); |
| 1855 | LLVMBuildRet(g->builder, value); |
| 1853 | 1856 | } |
| 1857 | return nullptr; |
| 1854 | 1858 | } |
| 1855 | 1859 | |
| 1856 | 1860 | static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { |