mirror of
https://github.com/ziglang/zig.git
synced 2026-02-11 20:11:23 +00:00
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
}
```
This commit is contained in:
parent
461382ae94
commit
ccce3d8526
@ -7278,6 +7278,6 @@ void src_assert(bool ok, AstNode *source_node) {
|
||||
buf_ptr(source_node->owner->data.structure.root_struct->path),
|
||||
(unsigned)source_node->line + 1, (unsigned)source_node->column + 1);
|
||||
}
|
||||
const char *msg = "assertion failed";
|
||||
const char *msg = "assertion failed. This is a bug in the Zig compiler.";
|
||||
stage2_panic(msg, strlen(msg));
|
||||
}
|
||||
|
||||
@ -1995,7 +1995,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
|
||||
if (!type_has_bits(instruction->value.type))
|
||||
return nullptr;
|
||||
if (!instruction->llvm_value) {
|
||||
assert(instruction->value.special != ConstValSpecialRuntime);
|
||||
src_assert(instruction->value.special != ConstValSpecialRuntime, instruction->source_node);
|
||||
assert(instruction->value.type);
|
||||
render_const_val(g, &instruction->value, "");
|
||||
// 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
|
||||
|
||||
if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {
|
||||
assert(g->cur_ret_ptr);
|
||||
gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);
|
||||
if (return_instruction->value->value.special != ConstValSpecialRuntime) {
|
||||
// if it's comptime we have to do this but if it's runtime trust that
|
||||
// result location mechanism took care of it.
|
||||
gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);
|
||||
}
|
||||
LLVMBuildRetVoid(g->builder);
|
||||
} else if (handle_is_ptr(return_type)) {
|
||||
LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, "");
|
||||
|
||||
11
src/ir.cpp
11
src/ir.cpp
@ -1382,6 +1382,9 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in
|
||||
FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack,
|
||||
ResultLoc *result_loc, ZigType *return_type)
|
||||
{
|
||||
// must be resolved before building the call instruction
|
||||
IrInstruction *resolved_result_loc = ir_resolve_result(ira, result_loc, return_type, nullptr);
|
||||
|
||||
IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb,
|
||||
source_instruction->scope, source_instruction->source_node);
|
||||
call_instruction->base.value.type = return_type;
|
||||
@ -1393,7 +1396,7 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in
|
||||
call_instruction->is_async = is_async;
|
||||
call_instruction->async_allocator = async_allocator;
|
||||
call_instruction->new_stack = new_stack;
|
||||
call_instruction->result_loc = ir_resolve_result(ira, result_loc, return_type, nullptr);
|
||||
call_instruction->result_loc = resolved_result_loc;
|
||||
|
||||
if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block);
|
||||
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
|
||||
}
|
||||
|
||||
// give nullptr for value to resolve it at runtime
|
||||
// returns a result location, or nullptr if the result location was already taken care of by this function
|
||||
// returns a result location, or nullptr if the result location was already taken care of
|
||||
static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, ZigType *value_type,
|
||||
IrInstruction *value)
|
||||
{
|
||||
if (result_loc->implicit_elem_type != nullptr) {
|
||||
// already resolved
|
||||
return nullptr;
|
||||
}
|
||||
result_loc->gen_instruction = value;
|
||||
result_loc->implicit_elem_type = value_type;
|
||||
switch (result_loc->id) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user