authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-31 01:36:57-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-31 01:36:57-04:00
logccce3d852681bfe60bce92a6766b4f431dd73571
tree521bf62dffb4d1c95be881a6c8c3d7208124c2eb
parent461382ae941e235ad75a6b3d00e05e5369baa98a
signaturelock-open Commit is signed but in an unrecognized format.

no-copy semantics for function forwarding

```zig fn foo() Foo { return bar(); } ``` ```llvm define internal fastcc void @foo(%Foo* nonnull sret) unnamed_addr #2 !dbg !48 { Entry: call fastcc void @bar(%Foo* sret %0), !dbg !52 ret void, !dbg !54 } ```

3 files changed, 16 insertions(+), 5 deletions(-)

src/analyze.cpp+1-1
...@@ -7278,6 +7278,6 @@ void src_assert(bool ok, AstNode *source_node) {...@@ -7278,6 +7278,6 @@ void src_assert(bool ok, AstNode *source_node) {
7278 buf_ptr(source_node->owner->data.structure.root_struct->path),7278 buf_ptr(source_node->owner->data.structure.root_struct->path),
7279 (unsigned)source_node->line + 1, (unsigned)source_node->column + 1);7279 (unsigned)source_node->line + 1, (unsigned)source_node->column + 1);
7280 }7280 }
7281 const char *msg = "assertion failed";7281 const char *msg = "assertion failed. This is a bug in the Zig compiler.";
7282 stage2_panic(msg, strlen(msg));7282 stage2_panic(msg, strlen(msg));
7283}7283}
src/codegen.cpp+6-2
...@@ -1995,7 +1995,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {...@@ -1995,7 +1995,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
1995 if (!type_has_bits(instruction->value.type))1995 if (!type_has_bits(instruction->value.type))
1996 return nullptr;1996 return nullptr;
1997 if (!instruction->llvm_value) {1997 if (!instruction->llvm_value) {
1998 assert(instruction->value.special != ConstValSpecialRuntime);1998 src_assert(instruction->value.special != ConstValSpecialRuntime, instruction->source_node);
1999 assert(instruction->value.type);1999 assert(instruction->value.type);
2000 render_const_val(g, &instruction->value, "");2000 render_const_val(g, &instruction->value, "");
2001 // we might have to do some pointer casting here due to the way union2001 // we might have to do some pointer casting here due to the way union
...@@ -2388,7 +2388,11 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns...@@ -2388,7 +2388,11 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
23882388
2389 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {2389 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {
2390 assert(g->cur_ret_ptr);2390 assert(g->cur_ret_ptr);
2391 gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);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 gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);
2395 }
2392 LLVMBuildRetVoid(g->builder);2396 LLVMBuildRetVoid(g->builder);
2393 } else if (handle_is_ptr(return_type)) {2397 } else if (handle_is_ptr(return_type)) {
2394 LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, "");2398 LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, "");
src/ir.cpp+9-2
...@@ -1382,6 +1382,9 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in...@@ -1382,6 +1382,9 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in
1382 FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack,1382 FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack,
1383 ResultLoc *result_loc, ZigType *return_type)1383 ResultLoc *result_loc, ZigType *return_type)
1384{1384{
1385 // must be resolved before building the call instruction
1386 IrInstruction *resolved_result_loc = ir_resolve_result(ira, result_loc, return_type, nullptr);
1387
1385 IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb,1388 IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb,
1386 source_instruction->scope, source_instruction->source_node);1389 source_instruction->scope, source_instruction->source_node);
1387 call_instruction->base.value.type = return_type;1390 call_instruction->base.value.type = return_type;
...@@ -1393,7 +1396,7 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in...@@ -1393,7 +1396,7 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in
1393 call_instruction->is_async = is_async;1396 call_instruction->is_async = is_async;
1394 call_instruction->async_allocator = async_allocator;1397 call_instruction->async_allocator = async_allocator;
1395 call_instruction->new_stack = new_stack;1398 call_instruction->new_stack = new_stack;
1396 call_instruction->result_loc = ir_resolve_result(ira, result_loc, return_type, nullptr);1399 call_instruction->result_loc = resolved_result_loc;
13971400
1398 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block);1401 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block);
1399 for (size_t i = 0; i < arg_count; i += 1)1402 for (size_t i = 0; i < arg_count; i += 1)
...@@ -14347,10 +14350,14 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, ResultLoc *result_lo...@@ -14347,10 +14350,14 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, ResultLoc *result_lo
14347}14350}
1434814351
14349// give nullptr for value to resolve it at runtime14352// give nullptr for value to resolve it at runtime
14350// returns a result location, or nullptr if the result location was already taken care of by this function14353// returns a result location, or nullptr if the result location was already taken care of
14351static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, ZigType *value_type,14354static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, ZigType *value_type,
14352 IrInstruction *value)14355 IrInstruction *value)
14353{14356{
14357 if (result_loc->implicit_elem_type != nullptr) {
14358 // already resolved
14359 return nullptr;
14360 }
14354 result_loc->gen_instruction = value;14361 result_loc->gen_instruction = value;
14355 result_loc->implicit_elem_type = value_type;14362 result_loc->implicit_elem_type = value_type;
14356 switch (result_loc->id) {14363 switch (result_loc->id) {