fix behavior for peer result locs with one prong unreachable

This commit is contained in:
Andrew Kelley 2019-06-07 14:20:35 -04:00
parent 4c222a482f
commit ec17f4ebbe
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
3 changed files with 21 additions and 10 deletions

View File

@ -33,9 +33,4 @@ handle if with no else
static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) {
IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_unreachable);
result->value.special = ConstValSpecialStatic;
return result;
}

View File

@ -3628,6 +3628,7 @@ struct IrSuspendPosition {
struct ResultLocPeer {
ResultLoc base;
bool seen_before;
ResultLocPeerParent *parent;
IrBasicBlock *next_bb;
IrSuspendPosition suspend_pos;

View File

@ -10659,6 +10659,12 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr
return result;
}
static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) {
IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_unreachable);
result->value.special = ConstValSpecialStatic;
return result;
}
static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) {
return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void);
}
@ -14461,7 +14467,9 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
if (peer_parent->resolved_type == nullptr) {
IrInstruction *suspended_inst = ira_suspend(ira, suspend_source_instr,
result_peer->next_bb, &result_peer->suspend_pos);
bool last_one = (result_peer == &peer_parent->peers[peer_parent->peer_count - 1]);
bool last_one = result_peer->seen_before ||
result_peer == &peer_parent->peers[peer_parent->peer_count - 1];
result_peer->seen_before = true;
if (!last_one) {
return suspended_inst;
}
@ -14472,13 +14480,20 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
IrInstruction *gen_instruction = this_peer->base.gen_instruction;
if (gen_instruction == nullptr) {
instructions[i] = ir_const(ira, this_peer->base.source_instruction,
this_peer->base.implicit_elem_type);
instructions[i]->value.special = ConstValSpecialRuntime;
// unreachable instructions will cause implicit_elem_type to be null
if (this_peer->base.implicit_elem_type == nullptr) {
instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction);
} else {
instructions[i] = ir_const(ira, this_peer->base.source_instruction,
this_peer->base.implicit_elem_type);
instructions[i]->value.special = ConstValSpecialRuntime;
}
} else {
instructions[i] = gen_instruction;
}
if (opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) {
if (opposite_peer->base.implicit_elem_type != nullptr &&
opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable)
{
ira->resume_stack.append(opposite_peer->suspend_pos);
}
}