authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-02 16:10:45-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-02 16:10:45-04:00
logb2d94f9af2968e01bd3d8db38c9ae1992bbd3678
tree3b1b518ebad8684cfa4f1a9f6f4f5a65830ecbcf
parent6cb4cac5cd1c68f41c62a3c23b09513988337c8d
parentd105769926fd5360a5309be3e202cc65d32ce604
signature Commit is signed but in an unrecognized format.

Merge branch 'assignment-result-loc'

With this merge, assignments participate in result location semantics.

7 files changed, 128 insertions(+), 57 deletions(-)

src/all_types.hpp+2
...@@ -2543,6 +2543,7 @@ struct IrInstructionLoadPtrGen {...@@ -2543,6 +2543,7 @@ struct IrInstructionLoadPtrGen {
2543struct IrInstructionStorePtr {2543struct IrInstructionStorePtr {
2544 IrInstruction base;2544 IrInstruction base;
25452545
2546 bool allow_write_through_const;
2546 IrInstruction *ptr;2547 IrInstruction *ptr;
2547 IrInstruction *value;2548 IrInstruction *value;
2548};2549};
...@@ -3707,6 +3708,7 @@ enum ResultLocId {...@@ -3707,6 +3708,7 @@ enum ResultLocId {
3707struct ResultLoc {3708struct ResultLoc {
3708 ResultLocId id;3709 ResultLocId id;
3709 bool written;3710 bool written;
3711 bool allow_write_through_const;
3710 IrInstruction *resolved_loc; // result ptr 3712 IrInstruction *resolved_loc; // result ptr
3711 IrInstruction *source_instruction;3713 IrInstruction *source_instruction;
3712 IrInstruction *gen_instruction; // value to store to the result loc3714 IrInstruction *gen_instruction; // value to store to the result loc
src/codegen.cpp+7-1
...@@ -4458,8 +4458,14 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn...@@ -4458,8 +4458,14 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn
4458 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");4458 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");
4459 }4459 }
44604460
4461 // When the cmpxchg is discarded, the result location will have no bits.
4462 if (!type_has_bits(instruction->result_loc->value.type)) {
4463 return nullptr;
4464 }
4465
4461 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);4466 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
4462 assert(type_has_bits(child_type));4467 src_assert(result_loc != nullptr, instruction->base.source_node);
4468 src_assert(type_has_bits(child_type), instruction->base.source_node);
44634469
4464 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");4470 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
4465 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");4471 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
src/ir.cpp+72-48
...@@ -189,7 +189,8 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_...@@ -189,7 +189,8 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_
189static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,189static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,
190 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime);190 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime);
191static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,191static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,
192 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime);192 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime,
193 bool non_null_comptime, bool allow_discard);
193static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,194static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,
194 IrInstruction *base_ptr, bool safety_check_on, bool initializing);195 IrInstruction *base_ptr, bool safety_check_on, bool initializing);
195static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr,196static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr,
...@@ -197,7 +198,7 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct...@@ -197,7 +198,7 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct
197static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr,198static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr,
198 IrInstruction *base_ptr, bool initializing);199 IrInstruction *base_ptr, bool initializing);
199static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,200static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,
200 IrInstruction *ptr, IrInstruction *uncasted_value);201 IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const);
201static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node,202static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node,
202 IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node,203 IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node,
203 LVal lval, ResultLoc *parent_result_loc);204 LVal lval, ResultLoc *parent_result_loc);
...@@ -1612,7 +1613,7 @@ static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode...@@ -1612,7 +1613,7 @@ static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode
1612 return &unreachable_instruction->base;1613 return &unreachable_instruction->base;
1613}1614}
16141615
1615static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,1616static IrInstructionStorePtr *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1616 IrInstruction *ptr, IrInstruction *value)1617 IrInstruction *ptr, IrInstruction *value)
1617{1618{
1618 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node);1619 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node);
...@@ -1624,7 +1625,7 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *...@@ -1624,7 +1625,7 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *
1624 ir_ref_instruction(ptr, irb->current_basic_block);1625 ir_ref_instruction(ptr, irb->current_basic_block);
1625 ir_ref_instruction(value, irb->current_basic_block);1626 ir_ref_instruction(value, irb->current_basic_block);
16261627
1627 return &instruction->base;1628 return instruction;
1628}1629}
16291630
1630static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node,1631static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
...@@ -4001,12 +4002,20 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no...@@ -4001,12 +4002,20 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no
40014002
4002static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) {4003static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) {
4003 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr);4004 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr);
4004 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);4005 if (lvalue == irb->codegen->invalid_instruction)
4006 return irb->codegen->invalid_instruction;
4007
4008 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
4009 result_loc_inst->base.id = ResultLocIdInstruction;
4010 result_loc_inst->base.source_instruction = lvalue;
4011 ir_ref_instruction(lvalue, irb->current_basic_block);
4012 ir_build_reset_result(irb, scope, node, &result_loc_inst->base);
40054013
4006 if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction)4014 IrInstruction *rvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op2, scope, LValNone,
4015 &result_loc_inst->base);
4016 if (rvalue == irb->codegen->invalid_instruction)
4007 return irb->codegen->invalid_instruction;4017 return irb->codegen->invalid_instruction;
40084018
4009 ir_build_store_ptr(irb, scope, node, lvalue, rvalue);
4010 return ir_build_const_void(irb, scope, node);4019 return ir_build_const_void(irb, scope, node);
4011}4020}
40124021
...@@ -6042,6 +6051,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A...@@ -6042,6 +6051,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
6042 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);6051 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
6043 result_loc_inst->base.id = ResultLocIdInstruction;6052 result_loc_inst->base.id = ResultLocIdInstruction;
6044 result_loc_inst->base.source_instruction = field_ptr;6053 result_loc_inst->base.source_instruction = field_ptr;
6054 result_loc_inst->base.allow_write_through_const = true;
6045 ir_ref_instruction(field_ptr, irb->current_basic_block);6055 ir_ref_instruction(field_ptr, irb->current_basic_block);
6046 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);6056 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);
60476057
...@@ -6080,6 +6090,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A...@@ -6080,6 +6090,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
6080 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);6090 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
6081 result_loc_inst->base.id = ResultLocIdInstruction;6091 result_loc_inst->base.id = ResultLocIdInstruction;
6082 result_loc_inst->base.source_instruction = elem_ptr;6092 result_loc_inst->base.source_instruction = elem_ptr;
6093 result_loc_inst->base.allow_write_through_const = true;
6083 ir_ref_instruction(elem_ptr, irb->current_basic_block);6094 ir_ref_instruction(elem_ptr, irb->current_basic_block);
6084 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);6095 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);
60856096
...@@ -6637,7 +6648,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -6637,7 +6648,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
66376648
6638 ir_set_cursor_at_end_and_append_block(irb, continue_block);6649 ir_set_cursor_at_end_and_append_block(irb, continue_block);
6639 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false);6650 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false);
6640 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val));6651 ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true;
6641 ir_build_br(irb, child_scope, node, cond_block, is_comptime);6652 ir_build_br(irb, child_scope, node, cond_block, is_comptime);
66426653
6643 IrInstruction *else_result = nullptr;6654 IrInstruction *else_result = nullptr;
...@@ -11155,7 +11166,8 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc...@@ -11155,7 +11166,8 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
11155 }11166 }
1115611167
11157 if (result_loc == nullptr) result_loc = no_result_loc();11168 if (result_loc == nullptr) result_loc = no_result_loc();
11158 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);11169 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true,
11170 false, true);
11159 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {11171 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11160 return result_loc_inst;11172 return result_loc_inst;
11161 }11173 }
...@@ -11615,7 +11627,7 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so...@@ -11615,7 +11627,7 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so
11615 }11627 }
11616 IrInstruction *result_loc_inst = nullptr;11628 IrInstruction *result_loc_inst = nullptr;
11617 if (result_loc != nullptr) {11629 if (result_loc != nullptr) {
11618 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);11630 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true);
11619 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {11631 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11620 return result_loc_inst;11632 return result_loc_inst;
11621 }11633 }
...@@ -11658,7 +11670,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction...@@ -11658,7 +11670,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
11658 IrInstruction *result_loc_inst;11670 IrInstruction *result_loc_inst;
11659 if (handle_is_ptr(wanted_type)) {11671 if (handle_is_ptr(wanted_type)) {
11660 if (result_loc == nullptr) result_loc = no_result_loc();11672 if (result_loc == nullptr) result_loc = no_result_loc();
11661 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);11673 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true);
11662 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {11674 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11663 return result_loc_inst;11675 return result_loc_inst;
11664 }11676 }
...@@ -11743,7 +11755,7 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so...@@ -11743,7 +11755,7 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so
11743 IrInstruction *result_loc_inst;11755 IrInstruction *result_loc_inst;
11744 if (handle_is_ptr(wanted_type)) {11756 if (handle_is_ptr(wanted_type)) {
11745 if (result_loc == nullptr) result_loc = no_result_loc();11757 if (result_loc == nullptr) result_loc = no_result_loc();
11746 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);11758 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true);
11747 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {11759 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11748 return result_loc_inst;11760 return result_loc_inst;
11749 }11761 }
...@@ -11816,7 +11828,8 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi...@@ -11816,7 +11828,8 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
1181611828
11817 IrInstruction *result_loc;11829 IrInstruction *result_loc;
11818 if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) {11830 if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) {
11819 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true, false);11831 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true,
11832 false, true);
11820 } else {11833 } else {
11821 result_loc = nullptr;11834 result_loc = nullptr;
11822 }11835 }
...@@ -11860,7 +11873,8 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s...@@ -11860,7 +11873,8 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s
11860 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false);11873 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false);
1186111874
11862 if (result_loc == nullptr) result_loc = no_result_loc();11875 if (result_loc == nullptr) result_loc = no_result_loc();
11863 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);11876 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr,
11877 true, false, true);
11864 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {11878 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11865 return result_loc_inst;11879 return result_loc_inst;
11866 }11880 }
...@@ -12516,7 +12530,8 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *...@@ -12516,7 +12530,8 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *
12516 if (result_loc == nullptr) {12530 if (result_loc == nullptr) {
12517 result_loc = no_result_loc();12531 result_loc = no_result_loc();
12518 }12532 }
12519 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, true, false);12533 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr,
12534 true, false, true);
12520 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {12535 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
12521 return result_loc_inst;12536 return result_loc_inst;
12522 }12537 }
...@@ -13097,7 +13112,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc...@@ -13097,7 +13112,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
13097 IrInstruction *result_loc_inst;13112 IrInstruction *result_loc_inst;
13098 if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) {13113 if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) {
13099 if (result_loc == nullptr) result_loc = no_result_loc();13114 if (result_loc == nullptr) result_loc = no_result_loc();
13100 result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, false);13115 result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr,
13116 true, false, true);
13101 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {13117 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
13102 return result_loc_inst;13118 return result_loc_inst;
13103 }13119 }
...@@ -14834,7 +14850,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,...@@ -14834,7 +14850,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
14834 // instruction.14850 // instruction.
14835 assert(deref->value.special != ConstValSpecialRuntime);14851 assert(deref->value.special != ConstValSpecialRuntime);
14836 var_ptr->value.special = ConstValSpecialRuntime;14852 var_ptr->value.special = ConstValSpecialRuntime;
14837 ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref);14853 ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref, false);
14838 }14854 }
1483914855
14840 if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) {14856 if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) {
...@@ -15352,7 +15368,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15352,7 +15368,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
1535215368
15353 if (peer_parent->peers.length == 1) {15369 if (peer_parent->peers.length == 1) {
15354 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,15370 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15355 value_type, value, force_runtime, non_null_comptime);15371 value_type, value, force_runtime, non_null_comptime, true);
15356 result_peer->suspend_pos.basic_block_index = SIZE_MAX;15372 result_peer->suspend_pos.basic_block_index = SIZE_MAX;
15357 result_peer->suspend_pos.instruction_index = SIZE_MAX;15373 result_peer->suspend_pos.instruction_index = SIZE_MAX;
15358 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||15374 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
...@@ -15372,7 +15388,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15372,7 +15388,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
15372 if (peer_parent->skipped) {15388 if (peer_parent->skipped) {
15373 if (non_null_comptime) {15389 if (non_null_comptime) {
15374 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,15390 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15375 value_type, value, force_runtime, non_null_comptime);15391 value_type, value, force_runtime, non_null_comptime, true);
15376 }15392 }
15377 return nullptr;15393 return nullptr;
15378 }15394 }
...@@ -15390,7 +15406,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15390,7 +15406,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
15390 }15406 }
1539115407
15392 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,15408 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15393 peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime);15409 peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime, true);
15394 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||15410 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
15395 parent_result_loc->value.type->id == ZigTypeIdUnreachable)15411 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
15396 {15412 {
...@@ -15440,7 +15456,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15440,7 +15456,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
15440 }15456 }
1544115457
15442 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent,15458 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent,
15443 dest_type, bitcasted_value, force_runtime, non_null_comptime);15459 dest_type, bitcasted_value, force_runtime, non_null_comptime, true);
15444 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||15460 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
15445 parent_result_loc->value.type->id == ZigTypeIdUnreachable)15461 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
15446 {15462 {
...@@ -15469,8 +15485,15 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15469,8 +15485,15 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
1546915485
15470static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,15486static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,
15471 ResultLoc *result_loc_pass1, ZigType *value_type, IrInstruction *value, bool force_runtime,15487 ResultLoc *result_loc_pass1, ZigType *value_type, IrInstruction *value, bool force_runtime,
15472 bool non_null_comptime)15488 bool non_null_comptime, bool allow_discard)
15473{15489{
15490 if (!allow_discard && result_loc_pass1->id == ResultLocIdInstruction &&
15491 instr_is_comptime(result_loc_pass1->source_instruction) &&
15492 result_loc_pass1->source_instruction->value.type->id == ZigTypeIdPointer &&
15493 result_loc_pass1->source_instruction->value.data.x_ptr.special == ConstPtrSpecialDiscard)
15494 {
15495 result_loc_pass1 = no_result_loc();
15496 }
15474 IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type,15497 IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type,
15475 value, force_runtime, non_null_comptime);15498 value, force_runtime, non_null_comptime);
15476 if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type)))15499 if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type)))
...@@ -15525,7 +15548,7 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn...@@ -15525,7 +15548,7 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn
15525 if (type_is_invalid(implicit_elem_type))15548 if (type_is_invalid(implicit_elem_type))
15526 return ira->codegen->invalid_instruction;15549 return ira->codegen->invalid_instruction;
15527 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,15550 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
15528 implicit_elem_type, nullptr, false, true);15551 implicit_elem_type, nullptr, false, true, true);
15529 if (result_loc != nullptr)15552 if (result_loc != nullptr)
15530 return result_loc;15553 return result_loc;
1553115554
...@@ -15534,7 +15557,7 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn...@@ -15534,7 +15557,7 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn
15534 instruction->result_loc->id == ResultLocIdReturn)15557 instruction->result_loc->id == ResultLocIdReturn)
15535 {15558 {
15536 result_loc = ir_resolve_result(ira, &instruction->base, no_result_loc(),15559 result_loc = ir_resolve_result(ira, &instruction->base, no_result_loc(),
15537 implicit_elem_type, nullptr, false, true);15560 implicit_elem_type, nullptr, false, true, true);
15538 if (result_loc != nullptr &&15561 if (result_loc != nullptr &&
15539 (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))15562 (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))
15540 {15563 {
...@@ -15623,7 +15646,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc...@@ -15623,7 +15646,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc
15623 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);15646 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
1562415647
15625 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(),15648 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(),
15626 async_return_type, nullptr, true, true);15649 async_return_type, nullptr, true, true, false);
15627 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {15650 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
15628 return result_loc;15651 return result_loc;
15629 }15652 }
...@@ -15841,7 +15864,7 @@ no_mem_slot:...@@ -15841,7 +15864,7 @@ no_mem_slot:
15841}15864}
1584215865
15843static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,15866static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,
15844 IrInstruction *ptr, IrInstruction *uncasted_value)15867 IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const)
15845{15868{
15846 assert(ptr->value.type->id == ZigTypeIdPointer);15869 assert(ptr->value.type->id == ZigTypeIdPointer);
1584715870
...@@ -15857,7 +15880,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -15857,7 +15880,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
1585715880
15858 ZigType *child_type = ptr->value.type->data.pointer.child_type;15881 ZigType *child_type = ptr->value.type->data.pointer.child_type;
1585915882
15860 if (ptr->value.type->data.pointer.is_const && !source_instr->is_gen) {15883 if (ptr->value.type->data.pointer.is_const && !allow_write_through_const) {
15861 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));15884 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
15862 return ira->codegen->invalid_instruction;15885 return ira->codegen->invalid_instruction;
15863 }15886 }
...@@ -15936,10 +15959,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -15936,10 +15959,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
15936 break;15959 break;
15937 }15960 }
1593815961
15939 IrInstruction *result = ir_build_store_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node,15962 IrInstructionStorePtr *store_ptr = ir_build_store_ptr(&ira->new_irb, source_instr->scope,
15940 ptr, value);15963 source_instr->source_node, ptr, value);
15941 result->value.type = ira->codegen->builtin_types.entry_void;15964 return &store_ptr->base;
15942 return result;
15943}15965}
1594415966
15945static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction,15967static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction,
...@@ -16382,7 +16404,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -16382,7 +16404,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
16382 IrInstruction *result_loc;16404 IrInstruction *result_loc;
16383 if (handle_is_ptr(impl_fn_type_id->return_type)) {16405 if (handle_is_ptr(impl_fn_type_id->return_type)) {
16384 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,16406 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
16385 impl_fn_type_id->return_type, nullptr, true, true);16407 impl_fn_type_id->return_type, nullptr, true, true, false);
16386 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) ||16408 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) ||
16387 instr_is_unreachable(result_loc)))16409 instr_is_unreachable(result_loc)))
16388 {16410 {
...@@ -16504,7 +16526,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -16504,7 +16526,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
16504 IrInstruction *result_loc;16526 IrInstruction *result_loc;
16505 if (handle_is_ptr(return_type)) {16527 if (handle_is_ptr(return_type)) {
16506 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,16528 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
16507 return_type, nullptr, true, true);16529 return_type, nullptr, true, true, false);
16508 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) {16530 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) {
16509 return result_loc;16531 return result_loc;
16510 }16532 }
...@@ -17020,7 +17042,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh...@@ -17020,7 +17042,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
1702017042
17021 // In case resolving the parent activates a suspend, do it now17043 // In case resolving the parent activates a suspend, do it now
17022 IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent,17044 IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent,
17023 peer_parent->resolved_type, nullptr, false, false);17045 peer_parent->resolved_type, nullptr, false, false, true);
17024 if (parent_result_loc != nullptr &&17046 if (parent_result_loc != nullptr &&
17025 (type_is_invalid(parent_result_loc->value.type) || instr_is_unreachable(parent_result_loc)))17047 (type_is_invalid(parent_result_loc->value.type) || instr_is_unreachable(parent_result_loc)))
17026 {17048 {
...@@ -17477,6 +17499,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17477,6 +17499,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17477 return result;17499 return result;
17478 } else if (is_slice(array_type)) {17500 } else if (is_slice(array_type)) {
17479 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];17501 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];
17502 ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base);
17480 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {17503 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
17481 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,17504 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
17482 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false,17505 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false,
...@@ -17663,7 +17686,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction...@@ -17663,7 +17686,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
17663 return ira->codegen->invalid_instruction;17686 return ira->codegen->invalid_instruction;
17664 if (type_is_invalid(struct_val->type))17687 if (type_is_invalid(struct_val->type))
17665 return ira->codegen->invalid_instruction;17688 return ira->codegen->invalid_instruction;
17666 if (struct_val->special == ConstValSpecialUndef && initializing) {17689 if (initializing && struct_val->special == ConstValSpecialUndef) {
17667 struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count);17690 struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count);
17668 struct_val->special = ConstValSpecialStatic;17691 struct_val->special = ConstValSpecialStatic;
17669 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {17692 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
...@@ -18261,7 +18284,7 @@ static IrInstruction *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstruc...@@ -18261,7 +18284,7 @@ static IrInstruction *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstruc
18261 if (type_is_invalid(value->value.type))18284 if (type_is_invalid(value->value.type))
18262 return ira->codegen->invalid_instruction;18285 return ira->codegen->invalid_instruction;
1826318286
18264 return ir_analyze_store_ptr(ira, &instruction->base, ptr, value);18287 return ir_analyze_store_ptr(ira, &instruction->base, ptr, value, instruction->allow_write_through_const);
18265}18288}
1826618289
18267static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *instruction) {18290static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *instruction) {
...@@ -18764,7 +18787,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr...@@ -18764,7 +18787,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
18764 if (optional_val == nullptr)18787 if (optional_val == nullptr)
18765 return ira->codegen->invalid_instruction;18788 return ira->codegen->invalid_instruction;
1876618789
18767 if (initializing && optional_val->special == ConstValSpecialUndef) {18790 if (initializing) {
18768 switch (type_has_one_possible_value(ira->codegen, child_type)) {18791 switch (type_has_one_possible_value(ira->codegen, child_type)) {
18769 case OnePossibleValueInvalid:18792 case OnePossibleValueInvalid:
18770 return ira->codegen->invalid_instruction;18793 return ira->codegen->invalid_instruction;
...@@ -19669,7 +19692,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -19669,7 +19692,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
1966919692
19670 IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc,19693 IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc,
19671 container_type, true);19694 container_type, true);
19672 ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst);19695 ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst, false);
19673 if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {19696 if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {
19674 const_ptrs.append(field_ptr);19697 const_ptrs.append(field_ptr);
19675 } else {19698 } else {
...@@ -19686,7 +19709,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -19686,7 +19709,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
19686 IrInstruction *field_result_loc = const_ptrs.at(i);19709 IrInstruction *field_result_loc = const_ptrs.at(i);
19687 IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr);19710 IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr);
19688 field_result_loc->value.special = ConstValSpecialRuntime;19711 field_result_loc->value.special = ConstValSpecialRuntime;
19689 ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref);19712 ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref, false);
19690 }19713 }
19691 }19714 }
19692 }19715 }
...@@ -19813,7 +19836,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -19813,7 +19836,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
19813 assert(elem_result_loc->value.special == ConstValSpecialStatic);19836 assert(elem_result_loc->value.special == ConstValSpecialStatic);
19814 IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr);19837 IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr);
19815 elem_result_loc->value.special = ConstValSpecialRuntime;19838 elem_result_loc->value.special = ConstValSpecialRuntime;
19816 ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref);19839 ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref, false);
19817 }19840 }
19818 }19841 }
19819 }19842 }
...@@ -21532,7 +21555,7 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi...@@ -21532,7 +21555,7 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi
21532 IrInstruction *result_loc;21555 IrInstruction *result_loc;
21533 if (handle_is_ptr(result_type)) {21556 if (handle_is_ptr(result_type)) {
21534 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,21557 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21535 result_type, nullptr, true, false);21558 result_type, nullptr, true, false, true);
21536 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {21559 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
21537 return result_loc;21560 return result_loc;
21538 }21561 }
...@@ -21789,7 +21812,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru...@@ -21789,7 +21812,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru
21789 }21812 }
2179021813
21791 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,21814 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21792 dest_slice_type, nullptr, true, false);21815 dest_slice_type, nullptr, true, false, true);
21793 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) {21816 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) {
21794 return result_loc;21817 return result_loc;
21795 }21818 }
...@@ -21866,7 +21889,7 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct...@@ -21866,7 +21889,7 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct
21866 }21889 }
2186721890
21868 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,21891 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21869 dest_slice_type, nullptr, true, false);21892 dest_slice_type, nullptr, true, false, true);
21870 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {21893 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
21871 return result_loc;21894 return result_loc;
21872 }21895 }
...@@ -22608,7 +22631,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction...@@ -22608,7 +22631,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
22608 }22631 }
2260922632
22610 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,22633 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
22611 return_type, nullptr, true, false);22634 return_type, nullptr, true, false, true);
22612 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {22635 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
22613 return result_loc;22636 return result_loc;
22614 }22637 }
...@@ -23260,7 +23283,7 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct...@@ -23260,7 +23283,7 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct
23260 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);23283 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
23261 if (err_union_val == nullptr)23284 if (err_union_val == nullptr)
23262 return ira->codegen->invalid_instruction;23285 return ira->codegen->invalid_instruction;
23263 if (err_union_val->special == ConstValSpecialUndef && initializing) {23286 if (initializing && err_union_val->special == ConstValSpecialUndef) {
23264 ConstExprValue *vals = create_const_vals(2);23287 ConstExprValue *vals = create_const_vals(2);
23265 ConstExprValue *err_set_val = &vals[0];23288 ConstExprValue *err_set_val = &vals[0];
23266 ConstExprValue *payload_val = &vals[1];23289 ConstExprValue *payload_val = &vals[1];
...@@ -25388,7 +25411,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct...@@ -25388,7 +25411,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct
2538825411
25389 bool was_written = instruction->result_loc->written;25412 bool was_written = instruction->result_loc->written;
25390 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,25413 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
25391 value->value.type, value, false, false);25414 value->value.type, value, false, false, true);
25392 if (result_loc != nullptr) {25415 if (result_loc != nullptr) {
25393 if (type_is_invalid(result_loc->value.type))25416 if (type_is_invalid(result_loc->value.type))
25394 return ira->codegen->invalid_instruction;25417 return ira->codegen->invalid_instruction;
...@@ -25396,7 +25419,8 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct...@@ -25396,7 +25419,8 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct
25396 return result_loc;25419 return result_loc;
2539725420
25398 if (!was_written) {25421 if (!was_written) {
25399 IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value);25422 IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value,
25423 instruction->result_loc->allow_write_through_const);
25400 if (type_is_invalid(store_ptr->value.type)) {25424 if (type_is_invalid(store_ptr->value.type)) {
25401 return ira->codegen->invalid_instruction;25425 return ira->codegen->invalid_instruction;
25402 }25426 }
...@@ -25420,7 +25444,7 @@ static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInst...@@ -25420,7 +25444,7 @@ static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInst
25420 return operand;25444 return operand;
2542125445
25422 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base,25446 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base,
25423 &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false);25447 &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false, true);
25424 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))25448 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))
25425 return result_loc;25449 return result_loc;
2542625450
test/compile_errors.zig+8-8
...@@ -201,7 +201,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -201,7 +201,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
201 \\ return error.OutOfMemory;201 \\ return error.OutOfMemory;
202 \\}202 \\}
203 ,203 ,
204 "tmp.zig:2:7: error: error is discarded",204 "tmp.zig:2:12: error: error is discarded",
205 );205 );
206206
207 cases.add(207 cases.add(
...@@ -2740,7 +2740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2740,7 +2740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2740 \\ 3 = 3;2740 \\ 3 = 3;
2741 \\}2741 \\}
2742 ,2742 ,
2743 "tmp.zig:2:7: error: cannot assign to constant",2743 "tmp.zig:2:9: error: cannot assign to constant",
2744 );2744 );
27452745
2746 cases.add(2746 cases.add(
...@@ -2750,7 +2750,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2750,7 +2750,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2750 \\ a = 4;2750 \\ a = 4;
2751 \\}2751 \\}
2752 ,2752 ,
2753 "tmp.zig:3:7: error: cannot assign to constant",2753 "tmp.zig:3:9: error: cannot assign to constant",
2754 );2754 );
27552755
2756 cases.add(2756 cases.add(
...@@ -2820,7 +2820,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2820,7 +2820,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2820 \\}2820 \\}
2821 \\export fn entry() void { f(); }2821 \\export fn entry() void { f(); }
2822 ,2822 ,
2823 "tmp.zig:3:7: error: cannot assign to constant",2823 "tmp.zig:3:9: error: cannot assign to constant",
2824 );2824 );
28252825
2826 cases.add(2826 cases.add(
...@@ -3883,7 +3883,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3883,7 +3883,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3883 \\3883 \\
3884 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }3884 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
3885 ,3885 ,
3886 "tmp.zig:6:24: error: unable to evaluate constant expression",3886 "tmp.zig:6:26: error: unable to evaluate constant expression",
3887 "tmp.zig:4:17: note: called from here",3887 "tmp.zig:4:17: note: called from here",
3888 );3888 );
38893889
...@@ -4133,7 +4133,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4133,7 +4133,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4133 \\ cstr[0] = 'W';4133 \\ cstr[0] = 'W';
4134 \\}4134 \\}
4135 ,4135 ,
4136 "tmp.zig:3:11: error: cannot assign to constant",4136 "tmp.zig:3:13: error: cannot assign to constant",
4137 );4137 );
41384138
4139 cases.add(4139 cases.add(
...@@ -4143,7 +4143,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4143,7 +4143,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4143 \\ cstr[0] = 'W';4143 \\ cstr[0] = 'W';
4144 \\}4144 \\}
4145 ,4145 ,
4146 "tmp.zig:3:11: error: cannot assign to constant",4146 "tmp.zig:3:13: error: cannot assign to constant",
4147 );4147 );
41484148
4149 cases.add(4149 cases.add(
...@@ -4291,7 +4291,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4291,7 +4291,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4291 \\ f.field = 0;4291 \\ f.field = 0;
4292 \\}4292 \\}
4293 ,4293 ,
4294 "tmp.zig:6:13: error: cannot assign to constant",4294 "tmp.zig:6:15: error: cannot assign to constant",
4295 );4295 );
42964296
4297 cases.add(4297 cases.add(
test/stage1/behavior/atomics.zig+10
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
3const builtin = @import("builtin");4const builtin = @import("builtin");
4const AtomicRmwOp = builtin.AtomicRmwOp;5const AtomicRmwOp = builtin.AtomicRmwOp;
5const AtomicOrder = builtin.AtomicOrder;6const AtomicOrder = builtin.AtomicOrder;
...@@ -90,3 +91,12 @@ test "cmpxchg with ptr" {...@@ -90,3 +91,12 @@ test "cmpxchg with ptr" {
90// expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);91// expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);
91// expect(x == 42);92// expect(x == 42);
92//}93//}
94
95test "cmpxchg with ignored result" {
96 var x: i32 = 1234;
97 var ptr = &x;
98
99 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);
100
101 expectEqual(i32(5678), x);
102}
test/stage1/behavior/eval.zig+10
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
3const builtin = @import("builtin");4const builtin = @import("builtin");
45
5test "compile time recursion" {6test "compile time recursion" {
...@@ -794,3 +795,12 @@ test "no undeclared identifier error in unanalyzed branches" {...@@ -794,3 +795,12 @@ test "no undeclared identifier error in unanalyzed branches" {
794 lol_this_doesnt_exist = nonsense;795 lol_this_doesnt_exist = nonsense;
795 }796 }
796}797}
798
799test "comptime assign int to optional int" {
800 comptime {
801 var x: ?i32 = null;
802 x = 2;
803 x.? *= 10;
804 expectEqual(20, x.?);
805 }
806}
test/stage1/behavior/fn.zig+19
...@@ -228,3 +228,22 @@ test "implicit cast fn call result to optional in field result" {...@@ -228,3 +228,22 @@ test "implicit cast fn call result to optional in field result" {
228 S.entry();228 S.entry();
229 comptime S.entry();229 comptime S.entry();
230}230}
231
232test "discard the result of a function that returns a struct" {
233 const S = struct {
234 fn entry() void {
235 _ = func();
236 }
237
238 fn func() Foo {
239 return undefined;
240 }
241
242 const Foo = struct {
243 a: u64,
244 b: u64,
245 };
246 };
247 S.entry();
248 comptime S.entry();
249}