| author | |
| committer | |
| log | ccce3d852681bfe60bce92a6766b4f431dd73571 |
| tree | 521bf62dffb4d1c95be881a6c8c3d7208124c2eb |
| parent | 461382ae941e235ad75a6b3d00e05e5369baa98a |
| signature |
```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 union | 2001 | // 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 |
| 2388 | 2388 | ||
| 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; |
| 1397 | 1400 | ||
| 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 | } |
| 14348 | 14351 | ||
| 14349 | // give nullptr for value to resolve it at runtime | 14352 | // 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 function | 14353 | // returns a result location, or nullptr if the result location was already taken care of |
| 14351 | static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, ZigType *value_type, | 14354 | static 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) { |