authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-02 15:17:02-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-02 15:17:02-04:00
log9069ee957cb8c9069028b325af5b862bbf8f66af
tree2eee1068703746456277bb31563ea117481a26ac
parent90e64bc620edc3f3c3a2c16d01b7ca2eefc02429
signature Commit is signed but in an unrecognized format.

fix discarding function call results


2 files changed, 58 insertions(+), 26 deletions(-)

src/ir.cpp+39-26
......@@ -189,7 +189,8 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_
189189static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,
190190 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime);
191191static 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);
193194static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,
194195 IrInstruction *base_ptr, bool safety_check_on, bool initializing);
195196static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr,
......@@ -11163,7 +11164,8 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
1116311164 }
1116411165
1116511166 if (result_loc == nullptr) result_loc = no_result_loc();
11166 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
11167 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true,
11168 false, true);
1116711169 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
1116811170 return result_loc_inst;
1116911171 }
......@@ -11623,7 +11625,7 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so
1162311625 }
1162411626 IrInstruction *result_loc_inst = nullptr;
1162511627 if (result_loc != nullptr) {
11626 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
11628 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true);
1162711629 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
1162811630 return result_loc_inst;
1162911631 }
......@@ -11666,7 +11668,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
1166611668 IrInstruction *result_loc_inst;
1166711669 if (handle_is_ptr(wanted_type)) {
1166811670 if (result_loc == nullptr) result_loc = no_result_loc();
11669 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
11671 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true);
1167011672 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
1167111673 return result_loc_inst;
1167211674 }
......@@ -11751,7 +11753,7 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so
1175111753 IrInstruction *result_loc_inst;
1175211754 if (handle_is_ptr(wanted_type)) {
1175311755 if (result_loc == nullptr) result_loc = no_result_loc();
11754 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
11756 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true);
1175511757 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
1175611758 return result_loc_inst;
1175711759 }
......@@ -11824,7 +11826,8 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
1182411826
1182511827 IrInstruction *result_loc;
1182611828 if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) {
11827 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true, false);
11829 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true,
11830 false, true);
1182811831 } else {
1182911832 result_loc = nullptr;
1183011833 }
......@@ -11868,7 +11871,8 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s
1186811871 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false);
1186911872
1187011873 if (result_loc == nullptr) result_loc = no_result_loc();
11871 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
11874 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr,
11875 true, false, true);
1187211876 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
1187311877 return result_loc_inst;
1187411878 }
......@@ -12524,7 +12528,8 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *
1252412528 if (result_loc == nullptr) {
1252512529 result_loc = no_result_loc();
1252612530 }
12527 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, true, false);
12531 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr,
12532 true, false, true);
1252812533 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
1252912534 return result_loc_inst;
1253012535 }
......@@ -13105,7 +13110,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
1310513110 IrInstruction *result_loc_inst;
1310613111 if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) {
1310713112 if (result_loc == nullptr) result_loc = no_result_loc();
13108 result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, false);
13113 result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr,
13114 true, false, true);
1310913115 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
1311013116 return result_loc_inst;
1311113117 }
......@@ -15360,7 +15366,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
1536015366
1536115367 if (peer_parent->peers.length == 1) {
1536215368 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15363 value_type, value, force_runtime, non_null_comptime);
15369 value_type, value, force_runtime, non_null_comptime, true);
1536415370 result_peer->suspend_pos.basic_block_index = SIZE_MAX;
1536515371 result_peer->suspend_pos.instruction_index = SIZE_MAX;
1536615372 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
......@@ -15380,7 +15386,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
1538015386 if (peer_parent->skipped) {
1538115387 if (non_null_comptime) {
1538215388 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15383 value_type, value, force_runtime, non_null_comptime);
15389 value_type, value, force_runtime, non_null_comptime, true);
1538415390 }
1538515391 return nullptr;
1538615392 }
......@@ -15398,7 +15404,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
1539815404 }
1539915405
1540015406 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15401 peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime);
15407 peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime, true);
1540215408 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
1540315409 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
1540415410 {
......@@ -15448,7 +15454,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
1544815454 }
1544915455
1545015456 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent,
15451 dest_type, bitcasted_value, force_runtime, non_null_comptime);
15457 dest_type, bitcasted_value, force_runtime, non_null_comptime, true);
1545215458 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
1545315459 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
1545415460 {
......@@ -15477,8 +15483,15 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
1547715483
1547815484static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,
1547915485 ResultLoc *result_loc_pass1, ZigType *value_type, IrInstruction *value, bool force_runtime,
15480 bool non_null_comptime)
15486 bool non_null_comptime, bool allow_discard)
1548115487{
15488 if (!allow_discard && result_loc_pass1->id == ResultLocIdInstruction &&
15489 instr_is_comptime(result_loc_pass1->source_instruction) &&
15490 result_loc_pass1->source_instruction->value.type->id == ZigTypeIdPointer &&
15491 result_loc_pass1->source_instruction->value.data.x_ptr.special == ConstPtrSpecialDiscard)
15492 {
15493 result_loc_pass1 = no_result_loc();
15494 }
1548215495 IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type,
1548315496 value, force_runtime, non_null_comptime);
1548415497 if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type)))
......@@ -15533,7 +15546,7 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn
1553315546 if (type_is_invalid(implicit_elem_type))
1553415547 return ira->codegen->invalid_instruction;
1553515548 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
15536 implicit_elem_type, nullptr, false, true);
15549 implicit_elem_type, nullptr, false, true, true);
1553715550 if (result_loc != nullptr)
1553815551 return result_loc;
1553915552
......@@ -15542,7 +15555,7 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn
1554215555 instruction->result_loc->id == ResultLocIdReturn)
1554315556 {
1554415557 result_loc = ir_resolve_result(ira, &instruction->base, no_result_loc(),
15545 implicit_elem_type, nullptr, false, true);
15558 implicit_elem_type, nullptr, false, true, true);
1554615559 if (result_loc != nullptr &&
1554715560 (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))
1554815561 {
......@@ -15631,7 +15644,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc
1563115644 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
1563215645
1563315646 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(),
15634 async_return_type, nullptr, true, true);
15647 async_return_type, nullptr, true, true, false);
1563515648 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
1563615649 return result_loc;
1563715650 }
......@@ -16390,7 +16403,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1639016403 IrInstruction *result_loc;
1639116404 if (handle_is_ptr(impl_fn_type_id->return_type)) {
1639216405 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
16393 impl_fn_type_id->return_type, nullptr, true, true);
16406 impl_fn_type_id->return_type, nullptr, true, true, false);
1639416407 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) ||
1639516408 instr_is_unreachable(result_loc)))
1639616409 {
......@@ -16512,7 +16525,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1651216525 IrInstruction *result_loc;
1651316526 if (handle_is_ptr(return_type)) {
1651416527 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
16515 return_type, nullptr, true, true);
16528 return_type, nullptr, true, true, false);
1651616529 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) {
1651716530 return result_loc;
1651816531 }
......@@ -17028,7 +17041,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
1702817041
1702917042 // In case resolving the parent activates a suspend, do it now
1703017043 IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent,
17031 peer_parent->resolved_type, nullptr, false, false);
17044 peer_parent->resolved_type, nullptr, false, false, true);
1703217045 if (parent_result_loc != nullptr &&
1703317046 (type_is_invalid(parent_result_loc->value.type) || instr_is_unreachable(parent_result_loc)))
1703417047 {
......@@ -21541,7 +21554,7 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi
2154121554 IrInstruction *result_loc;
2154221555 if (handle_is_ptr(result_type)) {
2154321556 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21544 result_type, nullptr, true, false);
21557 result_type, nullptr, true, false, true);
2154521558 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
2154621559 return result_loc;
2154721560 }
......@@ -21798,7 +21811,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru
2179821811 }
2179921812
2180021813 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21801 dest_slice_type, nullptr, true, false);
21814 dest_slice_type, nullptr, true, false, true);
2180221815 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) {
2180321816 return result_loc;
2180421817 }
......@@ -21875,7 +21888,7 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct
2187521888 }
2187621889
2187721890 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21878 dest_slice_type, nullptr, true, false);
21891 dest_slice_type, nullptr, true, false, true);
2187921892 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
2188021893 return result_loc;
2188121894 }
......@@ -22617,7 +22630,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
2261722630 }
2261822631
2261922632 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
22620 return_type, nullptr, true, false);
22633 return_type, nullptr, true, false, true);
2262122634 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
2262222635 return result_loc;
2262322636 }
......@@ -25397,7 +25410,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct
2539725410
2539825411 bool was_written = instruction->result_loc->written;
2539925412 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
25400 value->value.type, value, false, false);
25413 value->value.type, value, false, false, true);
2540125414 if (result_loc != nullptr) {
2540225415 if (type_is_invalid(result_loc->value.type))
2540325416 return ira->codegen->invalid_instruction;
......@@ -25429,7 +25442,7 @@ static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInst
2542925442 return operand;
2543025443
2543125444 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base,
25432 &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false);
25445 &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false, true);
2543325446 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))
2543425447 return result_loc;
2543525448
test/stage1/behavior/fn.zig+19
......@@ -228,3 +228,22 @@ test "implicit cast fn call result to optional in field result" {
228228 S.entry();
229229 comptime S.entry();
230230}
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}