result location semantics for error union wrapping an error
This commit is contained in:
parent
4f085b8d2c
commit
b9c033ae1a
|
@ -3109,8 +3109,8 @@ struct IrInstructionErrWrapPayload {
|
|||
struct IrInstructionErrWrapCode {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *value;
|
||||
LLVMValueRef tmp_ptr;
|
||||
IrInstruction *operand;
|
||||
IrInstruction *result_loc;
|
||||
};
|
||||
|
||||
struct IrInstructionFnProto {
|
||||
|
|
|
@ -4977,20 +4977,19 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable
|
|||
|
||||
assert(wanted_type->id == ZigTypeIdErrorUnion);
|
||||
|
||||
ZigType *payload_type = wanted_type->data.error_union.payload_type;
|
||||
ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
|
||||
LLVMValueRef err_val = ir_llvm_value(g, instruction->operand);
|
||||
|
||||
LLVMValueRef err_val = ir_llvm_value(g, instruction->value);
|
||||
|
||||
if (!type_has_bits(payload_type) || !type_has_bits(err_set_type))
|
||||
if (!handle_is_ptr(wanted_type))
|
||||
return err_val;
|
||||
|
||||
assert(instruction->tmp_ptr);
|
||||
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
|
||||
|
||||
LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
|
||||
LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
|
||||
gen_store_untyped(g, err_val, err_tag_ptr, 0, false);
|
||||
|
||||
return instruction->tmp_ptr;
|
||||
// TODO store undef to the payload
|
||||
|
||||
return result_loc;
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapPayload *instruction) {
|
||||
|
@ -6841,9 +6840,6 @@ static void do_code_gen(CodeGen *g) {
|
|||
slot = &ref_instruction->tmp_ptr;
|
||||
assert(instruction->value.type->id == ZigTypeIdPointer);
|
||||
slot_type = instruction->value.type->data.pointer.child_type;
|
||||
} else if (instruction->id == IrInstructionIdErrWrapCode) {
|
||||
IrInstructionErrWrapCode *err_wrap_code_instruction = (IrInstructionErrWrapCode *)instruction;
|
||||
slot = &err_wrap_code_instruction->tmp_ptr;
|
||||
} else if (instruction->id == IrInstructionIdCmpxchgGen) {
|
||||
IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction;
|
||||
slot = &cmpxchg_instruction->tmp_ptr;
|
||||
|
|
73
src/ir.cpp
73
src/ir.cpp
|
@ -1788,11 +1788,17 @@ static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *s
|
|||
return &instruction->base;
|
||||
}
|
||||
|
||||
static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
|
||||
IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node);
|
||||
instruction->value = value;
|
||||
static IrInstruction *ir_build_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instruction,
|
||||
ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
|
||||
{
|
||||
IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(
|
||||
&ira->new_irb, source_instruction->scope, source_instruction->source_node);
|
||||
instruction->base.value.type = result_type;
|
||||
instruction->operand = operand;
|
||||
instruction->result_loc = result_loc;
|
||||
|
||||
ir_ref_instruction(value, irb->current_basic_block);
|
||||
ir_ref_instruction(operand, ira->new_irb.current_basic_block);
|
||||
if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
|
||||
|
||||
return &instruction->base;
|
||||
}
|
||||
|
@ -11172,7 +11178,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou
|
|||
return result;
|
||||
}
|
||||
|
||||
static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) {
|
||||
static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
|
||||
ZigType *wanted_type, ResultLoc *result_loc)
|
||||
{
|
||||
assert(wanted_type->id == ZigTypeIdErrorUnion);
|
||||
|
||||
IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type);
|
||||
|
@ -11196,10 +11204,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so
|
|||
return &const_instruction->base;
|
||||
}
|
||||
|
||||
IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value);
|
||||
result->value.type = wanted_type;
|
||||
IrInstruction *result_loc_inst;
|
||||
if (handle_is_ptr(wanted_type)) {
|
||||
if (result_loc == nullptr) result_loc = no_result_loc();
|
||||
result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr);
|
||||
if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
|
||||
return result_loc_inst;
|
||||
}
|
||||
} else {
|
||||
result_loc_inst = nullptr;
|
||||
}
|
||||
|
||||
|
||||
IrInstruction *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst);
|
||||
result->value.data.rh_error_union = RuntimeHintErrorUnionError;
|
||||
ir_add_alloca(ira, result, wanted_type);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -12293,7 +12311,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||
if (wanted_type->id == ZigTypeIdErrorUnion &&
|
||||
actual_type->id == ZigTypeIdErrorSet)
|
||||
{
|
||||
return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type);
|
||||
return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type, result_loc);
|
||||
}
|
||||
|
||||
// cast from typed number to integer or float literal.
|
||||
|
@ -15615,12 +15633,16 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
|
|||
}
|
||||
|
||||
FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id;
|
||||
IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
|
||||
impl_fn_type_id->return_type, nullptr);
|
||||
if (result_loc != nullptr &&
|
||||
(type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable))
|
||||
{
|
||||
return result_loc;
|
||||
IrInstruction *result_loc;
|
||||
if (handle_is_ptr(impl_fn_type_id->return_type)) {
|
||||
result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
|
||||
impl_fn_type_id->return_type, nullptr);
|
||||
if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
|
||||
return result_loc;
|
||||
}
|
||||
call_instruction->result_loc->written = true;
|
||||
} else {
|
||||
result_loc = nullptr;
|
||||
}
|
||||
|
||||
if (fn_type_can_fail(impl_fn_type_id)) {
|
||||
|
@ -15634,7 +15656,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
|
|||
return ir_finish_anal(ira, result);
|
||||
}
|
||||
|
||||
call_instruction->result_loc->written = handle_is_ptr(impl_fn_type_id->return_type);
|
||||
assert(async_allocator_inst == nullptr);
|
||||
IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,
|
||||
impl_fn, nullptr, impl_param_count, casted_args, fn_inline,
|
||||
|
@ -15733,15 +15754,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
|
|||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
|
||||
IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
|
||||
return_type, nullptr);
|
||||
if (result_loc != nullptr &&
|
||||
(type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable))
|
||||
{
|
||||
return result_loc;
|
||||
IrInstruction *result_loc;
|
||||
if (handle_is_ptr(return_type)) {
|
||||
result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
|
||||
return_type, nullptr);
|
||||
if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
|
||||
return result_loc;
|
||||
}
|
||||
call_instruction->result_loc->written = true;
|
||||
} else {
|
||||
result_loc = nullptr;
|
||||
}
|
||||
|
||||
call_instruction->result_loc->written = handle_is_ptr(return_type);
|
||||
IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref,
|
||||
call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack,
|
||||
result_loc, return_type);
|
||||
|
@ -24462,7 +24486,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
|
|||
case IrInstructionIdHandle:
|
||||
case IrInstructionIdTestErr:
|
||||
case IrInstructionIdUnwrapErrCode:
|
||||
case IrInstructionIdErrWrapCode:
|
||||
case IrInstructionIdFnProto:
|
||||
case IrInstructionIdTestComptime:
|
||||
case IrInstructionIdPtrCastSrc:
|
||||
|
@ -24529,6 +24552,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
|
|||
}
|
||||
case IrInstructionIdErrWrapPayload:
|
||||
return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;
|
||||
case IrInstructionIdErrWrapCode:
|
||||
return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
|
|
@ -979,8 +979,9 @@ static void ir_print_optional_wrap(IrPrint *irp, IrInstructionOptionalWrap *inst
|
|||
|
||||
static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instruction) {
|
||||
fprintf(irp->f, "@errWrapCode(");
|
||||
ir_print_other_instruction(irp, instruction->value);
|
||||
fprintf(irp->f, ")");
|
||||
ir_print_other_instruction(irp, instruction->operand);
|
||||
fprintf(irp->f, ")result=");
|
||||
ir_print_other_instruction(irp, instruction->result_loc);
|
||||
}
|
||||
|
||||
static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user