diff --git a/src/analyze.cpp b/src/analyze.cpp index a62c24460e..24c81d2a3f 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -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)); } diff --git a/src/codegen.cpp b/src/codegen.cpp index ccbf911686..d468b60183 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -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, ""); diff --git a/src/ir.cpp b/src/ir.cpp index f700404f29..3420a85fce 100644 --- a/src/ir.cpp +++ b/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(&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) {