authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-13 16:02:18-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-13 16:02:18-05:00
log04c047463b2679c588c3fb09f3dace80aebd5723
tree9ed852c7288ffba0500ae0d15da3dc51957d1ffc
parente2fd3b2b1b512197e100af0a6b6e5bd96707d792

IR: fix hang for unreachable functions


1 files changed, 26 insertions(+), 27 deletions(-)

src/ir.cpp+26-27
......@@ -2074,6 +2074,11 @@ static void ir_inline_bb(IrAnalyze *ira, IrBasicBlock *old_bb) {
20742074 ira->old_irb.current_basic_block = old_bb;
20752075}
20762076
2077static TypeTableEntry *ir_finish_anal(IrAnalyze *ira, TypeTableEntry *result_type) {
2078 if (result_type->id == TypeTableEntryIdUnreachable)
2079 ir_finish_bb(ira);
2080 return result_type;
2081}
20772082
20782083static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_instruction,
20792084 bool depends_on_compile_var)
......@@ -2485,21 +2490,16 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira,
24852490 IrInstructionReturn *return_instruction)
24862491{
24872492 IrInstruction *value = return_instruction->value->other;
2488 if (value == ira->codegen->invalid_instruction) {
2489 ir_finish_bb(ira);
2490 return ira->codegen->builtin_types.entry_unreachable;
2491 }
2493 if (value == ira->codegen->invalid_instruction)
2494 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
24922495 ira->implicit_return_type_list.append(value);
24932496
24942497 IrInstruction *casted_value = ir_get_casted_value(ira, value, ira->explicit_return_type);
2495 if (casted_value == ira->codegen->invalid_instruction) {
2496 ir_finish_bb(ira);
2497 return ira->codegen->builtin_types.entry_unreachable;
2498 }
2498 if (casted_value == ira->codegen->invalid_instruction)
2499 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
24992500
25002501 ir_build_return_from(&ira->new_irb, &return_instruction->base, casted_value);
2501 ir_finish_bb(ira);
2502 return ira->codegen->builtin_types.entry_unreachable;
2502 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
25032503}
25042504
25052505static TypeTableEntry *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *const_instruction) {
......@@ -2975,7 +2975,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
29752975 return ira->codegen->builtin_types.entry_invalid;
29762976
29772977 ir_link_new_instruction(cast_instruction, &call_instruction->base);
2978 return cast_instruction->type_entry;
2978 return ir_finish_anal(ira, cast_instruction->type_entry);
29792979 } else if (fn_ref->type_entry->id == TypeTableEntryIdFn) {
29802980 // TODO fully port over the fn call analyze code to IR
29812981 FnTableEntry *fn_table_entry = fn_ref->static_value.data.x_fn;
......@@ -2985,14 +2985,15 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
29852985 for (size_t i = 0; i < call_instruction->arg_count; i += 1) {
29862986 TypeTableEntry *param_type = fn_type->data.fn.fn_type_id.param_info[i].type;
29872987 IrInstruction *old_arg = call_instruction->args[i]->other;
2988 if (old_arg->type_entry->id == TypeTableEntryIdInvalid)
2989 return ira->codegen->builtin_types.entry_invalid;
29882990 casted_args[i] = ir_get_casted_value(ira, old_arg, param_type);
29892991 }
29902992
29912993 ir_build_call_from(&ira->new_irb, &call_instruction->base,
29922994 call_instruction->fn, call_instruction->arg_count, casted_args);
29932995
2994 TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type;
2995 return return_type;
2996 return ir_finish_anal(ira, fn_type->data.fn.fn_type_id.return_type);
29962997 } else {
29972998 zig_panic("TODO analyze more fn call types");
29982999 }
......@@ -3298,17 +3299,14 @@ static TypeTableEntry *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr
32983299
32993300 IrBasicBlock *new_bb = ir_get_new_bb(ira, old_dest_block);
33003301 ir_build_br_from(&ira->new_irb, &br_instruction->base, new_bb);
3301 ir_finish_bb(ira);
3302 return ira->codegen->builtin_types.entry_unreachable;
3302 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
33033303}
33043304
33053305static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) {
33063306 TypeTableEntry *bool_type = ira->codegen->builtin_types.entry_bool;
33073307 IrInstruction *condition = ir_get_casted_value(ira, cond_br_instruction->condition->other, bool_type);
3308 if (condition == ira->codegen->invalid_instruction) {
3309 ir_finish_bb(ira);
3310 return ira->codegen->builtin_types.entry_unreachable;
3311 }
3308 if (condition == ira->codegen->invalid_instruction)
3309 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
33123310
33133311 // TODO detect backward jumps
33143312 if (condition->static_value.ok) {
......@@ -3322,23 +3320,20 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct
33223320 } else if (cond_br_instruction->is_inline) {
33233321 add_node_error(ira->codegen, condition->source_node,
33243322 buf_sprintf("unable to evaluate constant expression"));
3325 ir_finish_bb(ira);
3326 return ira->codegen->builtin_types.entry_unreachable;
3323 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
33273324 }
33283325
33293326 IrBasicBlock *new_then_block = ir_get_new_bb(ira, cond_br_instruction->then_block);
33303327 IrBasicBlock *new_else_block = ir_get_new_bb(ira, cond_br_instruction->else_block);
33313328 ir_build_cond_br_from(&ira->new_irb, &cond_br_instruction->base, condition, new_then_block, new_else_block, false);
3332 ir_finish_bb(ira);
3333 return ira->codegen->builtin_types.entry_unreachable;
3329 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
33343330}
33353331
33363332static TypeTableEntry *ir_analyze_instruction_unreachable(IrAnalyze *ira,
33373333 IrInstructionUnreachable *unreachable_instruction)
33383334{
33393335 ir_build_unreachable_from(&ira->new_irb, &unreachable_instruction->base);
3340 ir_finish_bb(ira);
3341 return ira->codegen->builtin_types.entry_unreachable;
3336 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
33423337}
33433338
33443339static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) {
......@@ -3984,8 +3979,12 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl
39843979 ira->instruction_index += 1;
39853980 }
39863981
3987 return ir_resolve_peer_types(ira, expected_type_source_node, ira->implicit_return_type_list.items,
3988 ira->implicit_return_type_list.length);
3982 if (ira->implicit_return_type_list.length == 0) {
3983 return codegen->builtin_types.entry_unreachable;
3984 } else {
3985 return ir_resolve_peer_types(ira, expected_type_source_node, ira->implicit_return_type_list.items,
3986 ira->implicit_return_type_list.length);
3987 }
39893988}
39903989
39913990bool ir_has_side_effects(IrInstruction *instruction) {