authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-11 12:19:57-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-11 12:19:57-04:00
log06f307ff77adac0451b10643a033714c1d309010
tree9e7732bf00d5953899847299d6484ab62534fb14
parenta431a73dabd205667c1226e4d265fca0d25e6356
signaturelock-open Commit is signed but in an unrecognized format.

fix implicit casting return value struct/arary init to optional


5 files changed, 65 insertions(+), 32 deletions(-)

BRANCH_TODO+3
......@@ -1,6 +1,9 @@
11Scratch pad for stuff to do before merging master
22=================================================
33
4struct & array init when the result is casted to anyerror!T
5struct & array init when the result is casted to anyerror!?T
6
47uncomment all the behavior tests
58
69look at all the ir_gen_node ir_gen_node_extra calls and make sure result locations are properly propagated
src/all_types.hpp+2-1
......@@ -2770,8 +2770,9 @@ struct IrInstructionTestNonNull {
27702770struct IrInstructionOptionalUnwrapPtr {
27712771 IrInstruction base;
27722772
2773 IrInstruction *base_ptr;
27742773 bool safety_check_on;
2774 bool initializing;
2775 IrInstruction *base_ptr;
27752776};
27762777
27772778struct IrInstructionCtz {
src/codegen.cpp+22-15
......@@ -838,9 +838,7 @@ static LLVMValueRef gen_store_untyped(CodeGen *g, LLVMValueRef value, LLVMValueR
838838{
839839 LLVMValueRef instruction = LLVMBuildStore(g->builder, value, ptr);
840840 if (is_volatile) LLVMSetVolatile(instruction, true);
841 if (alignment == 0) {
842 LLVMSetAlignment(instruction, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(value)));
843 } else {
841 if (alignment != 0) {
844842 LLVMSetAlignment(instruction, alignment);
845843 }
846844 return instruction;
......@@ -2384,16 +2382,19 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut
23842382}
23852383
23862384static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {
2385 if (return_instruction->value == nullptr) {
2386 LLVMBuildRetVoid(g->builder);
2387 return nullptr;
2388 }
2389
23872390 ZigType *return_type = return_instruction->value->value.type;
23882391
23892392 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {
23902393 assert(g->cur_ret_ptr);
2391 if (return_instruction->value->value.special != ConstValSpecialRuntime) {
2392 // if it's comptime we have to do this but if it's runtime trust that
2393 // result location mechanism took care of it.
2394 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2395 gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);
2396 }
2394 src_assert(return_instruction->value->value.special != ConstValSpecialRuntime,
2395 return_instruction->base.source_node);
2396 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2397 gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);
23972398 LLVMBuildRetVoid(g->builder);
23982399 } else if (handle_is_ptr(return_type)) {
23992400 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
......@@ -4068,9 +4069,9 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *exec
40684069 ZigType *maybe_type = ptr_type->data.pointer.child_type;
40694070 assert(maybe_type->id == ZigTypeIdOptional);
40704071 ZigType *child_type = maybe_type->data.maybe.child_type;
4071 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->base_ptr);
4072 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on) {
4073 LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);
4072 LLVMValueRef base_ptr = ir_llvm_value(g, instruction->base_ptr);
4073 if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) {
4074 LLVMValueRef maybe_handle = get_handle_value(g, base_ptr, maybe_type, ptr_type);
40744075 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);
40754076 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalFail");
40764077 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk");
......@@ -4086,10 +4087,16 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *exec
40864087 } else {
40874088 bool is_scalar = !handle_is_ptr(maybe_type);
40884089 if (is_scalar) {
4089 return maybe_ptr;
4090 return base_ptr;
40904091 } else {
4091 LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);
4092 return LLVMBuildStructGEP(g->builder, maybe_struct_ref, maybe_child_index, "");
4092 LLVMValueRef optional_struct_ref = get_handle_value(g, base_ptr, maybe_type, ptr_type);
4093 if (instruction->initializing) {
4094 LLVMValueRef non_null_bit_ptr = LLVMBuildStructGEP(g->builder, optional_struct_ref,
4095 maybe_null_index, "");
4096 LLVMValueRef non_null_bit = LLVMConstInt(LLVMInt1Type(), 1, false);
4097 gen_store_untyped(g, non_null_bit, non_null_bit_ptr, 0, false);
4098 }
4099 return LLVMBuildStructGEP(g->builder, optional_struct_ref, maybe_child_index, "");
40934100 }
40944101 }
40954102}
src/ir.cpp+35-14
......@@ -187,6 +187,8 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_
187187 ZigType *dest_type);
188188static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,
189189 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value);
190static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,
191 IrInstruction *base_ptr, bool safety_check_on, bool initializing);
190192
191193static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
192194 assert(get_src_ptr_type(const_val->type) != nullptr);
......@@ -1095,13 +1097,15 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *so
10951097 return &cond_br_instruction->base;
10961098}
10971099
1098static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *return_value) {
1100static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node,
1101 IrInstruction *return_value)
1102{
10991103 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node);
11001104 return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable;
11011105 return_instruction->base.value.special = ConstValSpecialStatic;
11021106 return_instruction->value = return_value;
11031107
1104 ir_ref_instruction(return_value, irb->current_basic_block);
1108 if (return_value != nullptr) ir_ref_instruction(return_value, irb->current_basic_block);
11051109
11061110 return &return_instruction->base;
11071111}
......@@ -1756,11 +1760,12 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod
17561760}
17571761
17581762static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1759 IrInstruction *base_ptr, bool safety_check_on)
1763 IrInstruction *base_ptr, bool safety_check_on, bool initializing)
17601764{
17611765 IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node);
17621766 instruction->base_ptr = base_ptr;
17631767 instruction->safety_check_on = safety_check_on;
1768 instruction->initializing = initializing;
17641769
17651770 ir_ref_instruction(base_ptr, irb->current_basic_block);
17661771
......@@ -3918,7 +3923,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
39183923 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime));
39193924
39203925 ir_set_cursor_at_end_and_append_block(irb, ok_block);
3921 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false);
3926 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false);
39223927 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr);
39233928 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers[1].base);
39243929 IrBasicBlock *after_ok_block = irb->current_basic_block;
......@@ -6009,7 +6014,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
60096014 ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, end_block, result_loc);
60106015
60116016 ir_set_cursor_at_end_and_append_block(irb, body_block);
6012 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false);
6017 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false, false);
60136018 IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ?
60146019 ir_build_ref(irb, child_scope, symbol_node, payload_ptr, true, false) : payload_ptr;
60156020 ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, var_ptr);
......@@ -6609,7 +6614,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
66096614 ZigVar *var = ir_create_var(irb, node, subexpr_scope,
66106615 var_symbol, is_const, is_const, is_shadowable, is_comptime);
66116616
6612 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false);
6617 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false);
66136618 IrInstruction *var_ptr = var_is_ptr ? ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr;
66146619 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr);
66156620 var_scope = var->child_scope;
......@@ -8094,7 +8099,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
80948099 if (maybe_ptr == irb->codegen->invalid_instruction)
80958100 return irb->codegen->invalid_instruction;
80968101
8097 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true);
8102 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true, false);
80988103 if (lval == LValPtr)
80998104 return unwrapped_ptr;
81008105
......@@ -8375,7 +8380,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
83758380 // a register or local variable which does not get spilled into the frame,
83768381 // otherwise llvm tries to access memory inside the destroyed frame.
83778382 IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node,
8378 irb->exec->await_handle_var_ptr, false);
8383 irb->exec->await_handle_var_ptr, false, false);
83798384 IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr);
83808385 ir_build_br(irb, scope, node, check_free_block, const_bool_false);
83818386
......@@ -12871,6 +12876,14 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
1287112876 if (type_is_invalid(value->value.type))
1287212877 return ir_unreach_error(ira);
1287312878
12879 if (!instr_is_comptime(value) && handle_is_ptr(ira->explicit_return_type)) {
12880 // result location mechanism took care of it.
12881 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
12882 instruction->base.source_node, nullptr);
12883 result->value.type = ira->codegen->builtin_types.entry_unreachable;
12884 return ir_finish_anal(ira, result);
12885 }
12886
1287412887 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type);
1287512888 if (type_is_invalid(casted_value->value.type)) {
1287612889 AstNode *source_node = ira->explicit_return_type_source_node;
......@@ -14925,10 +14938,17 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns
1492514938}
1492614939
1492714940static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) {
14928 ZigType *ty = ir_resolve_type(ira, instruction->ty->child);
14929 if (type_is_invalid(ty))
14941 ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child);
14942 if (type_is_invalid(implicit_elem_type))
1493014943 return ira->codegen->invalid_instruction;
14931 return ir_resolve_result(ira, &instruction->base, instruction->result_loc, ty, nullptr);
14944 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
14945 implicit_elem_type, nullptr);
14946 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
14947 ZigType *actual_elem_type = result_loc->value.type->data.pointer.child_type;
14948 if (actual_elem_type->id == ZigTypeIdOptional && implicit_elem_type->id != ZigTypeIdOptional) {
14949 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, result_loc, false, true);
14950 }
14951 return result_loc;
1493214952}
1493314953
1493414954static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,
......@@ -17876,7 +17896,7 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns
1787617896}
1787717897
1787817898static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,
17879 IrInstruction *base_ptr, bool safety_check_on)
17899 IrInstruction *base_ptr, bool safety_check_on, bool initializing)
1788017900{
1788117901 ZigType *ptr_type = base_ptr->value.type;
1788217902 assert(ptr_type->id == ZigTypeIdPointer);
......@@ -17948,7 +17968,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
1794817968 }
1794917969
1795017970 IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope,
17951 source_instr->source_node, base_ptr, safety_check_on);
17971 source_instr->source_node, base_ptr, safety_check_on, initializing);
1795217972 result->value.type = result_type;
1795317973 return result;
1795417974}
......@@ -17960,7 +17980,8 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira,
1796017980 if (type_is_invalid(base_ptr->value.type))
1796117981 return ira->codegen->invalid_instruction;
1796217982
17963 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on);
17983 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr,
17984 instruction->safety_check_on, false);
1796417985}
1796517986
1796617987static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) {
src/ir_print.cpp+3-2
......@@ -61,9 +61,10 @@ static void ir_print_other_block(IrPrint *irp, IrBasicBlock *bb) {
6161}
6262
6363static void ir_print_return(IrPrint *irp, IrInstructionReturn *return_instruction) {
64 assert(return_instruction->value);
6564 fprintf(irp->f, "return ");
66 ir_print_other_instruction(irp, return_instruction->value);
65 if (return_instruction->value != nullptr) {
66 ir_print_other_instruction(irp, return_instruction->value);
67 }
6768}
6869
6970static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction) {