| ... | ... | @@ -880,7 +880,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte |
| 880 | 880 | case ZigTypeIdComptimeFloat: |
| 881 | 881 | case ZigTypeIdComptimeInt: |
| 882 | 882 | case ZigTypeIdEnumLiteral: |
| 883 | | case ZigTypeIdPointer: |
| 884 | 883 | case ZigTypeIdUndefined: |
| 885 | 884 | case ZigTypeIdNull: |
| 886 | 885 | case ZigTypeIdBoundFn: |
| ... | ... | @@ -889,6 +888,8 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte |
| 889 | 888 | case ZigTypeIdAnyFrame: |
| 890 | 889 | case ZigTypeIdFn: |
| 891 | 890 | return true; |
| 891 | case ZigTypeIdPointer: |
| 892 | return expected->data.pointer.inferred_struct_field == actual->data.pointer.inferred_struct_field; |
| 892 | 893 | case ZigTypeIdFloat: |
| 893 | 894 | return expected->data.floating.bit_count == actual->data.floating.bit_count; |
| 894 | 895 | case ZigTypeIdInt: |
| ... | ... | @@ -7014,6 +7015,7 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod |
| 7014 | 7015 | ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1); |
| 7015 | 7016 | result_loc_bit_cast->base.id = ResultLocIdBitCast; |
| 7016 | 7017 | result_loc_bit_cast->base.source_instruction = dest_type; |
| 7018 | result_loc_bit_cast->base.allow_write_through_const = result_loc->allow_write_through_const; |
| 7017 | 7019 | ir_ref_instruction(dest_type, irb->current_basic_block); |
| 7018 | 7020 | result_loc_bit_cast->parent = result_loc; |
| 7019 | 7021 | |
| ... | ... | @@ -13597,32 +13599,31 @@ static IrInstGen *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInst *source_in |
| 13597 | 13599 | return result; |
| 13598 | 13600 | } |
| 13599 | 13601 | |
| 13600 | | static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, |
| 13601 | | bool is_const, bool is_volatile) |
| 13602 | static IrInstGen *ir_get_ref2(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, |
| 13603 | ZigType *elem_type, bool is_const, bool is_volatile) |
| 13602 | 13604 | { |
| 13603 | 13605 | Error err; |
| 13604 | 13606 | |
| 13605 | | if (type_is_invalid(value->value->type)) |
| 13607 | if (type_is_invalid(elem_type)) |
| 13606 | 13608 | return ira->codegen->invalid_inst_gen; |
| 13607 | 13609 | |
| 13608 | 13610 | if (instr_is_comptime(value)) { |
| 13609 | 13611 | ZigValue *val = ir_resolve_const(ira, value, LazyOk); |
| 13610 | 13612 | if (!val) |
| 13611 | 13613 | return ira->codegen->invalid_inst_gen; |
| 13612 | | return ir_get_const_ptr(ira, source_instruction, val, value->value->type, |
| 13614 | return ir_get_const_ptr(ira, source_instruction, val, elem_type, |
| 13613 | 13615 | ConstPtrMutComptimeConst, is_const, is_volatile, 0); |
| 13614 | 13616 | } |
| 13615 | 13617 | |
| 13616 | | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value->type, |
| 13618 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type, |
| 13617 | 13619 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 13618 | 13620 | |
| 13619 | 13621 | if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown))) |
| 13620 | 13622 | return ira->codegen->invalid_inst_gen; |
| 13621 | 13623 | |
| 13622 | 13624 | IrInstGen *result_loc; |
| 13623 | | if (type_has_bits(ptr_type) && !handle_is_ptr(value->value->type)) { |
| 13624 | | result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value->type, |
| 13625 | | nullptr, true, true); |
| 13625 | if (type_has_bits(ptr_type) && !handle_is_ptr(elem_type)) { |
| 13626 | result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), elem_type, nullptr, true, true); |
| 13626 | 13627 | } else { |
| 13627 | 13628 | result_loc = nullptr; |
| 13628 | 13629 | } |
| ... | ... | @@ -13632,6 +13633,12 @@ static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstG |
| 13632 | 13633 | return new_instruction; |
| 13633 | 13634 | } |
| 13634 | 13635 | |
| 13636 | static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, |
| 13637 | bool is_const, bool is_volatile) |
| 13638 | { |
| 13639 | return ir_get_ref2(ira, source_instruction, value, value->value->type, is_const, is_volatile); |
| 13640 | } |
| 13641 | |
| 13635 | 13642 | static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, AstNode *source_node, ZigType *union_type) { |
| 13636 | 13643 | assert(union_type->id == ZigTypeIdUnion); |
| 13637 | 13644 | |
| ... | ... | @@ -18204,6 +18211,21 @@ static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_sourc |
| 18204 | 18211 | return result_loc->resolved_loc; |
| 18205 | 18212 | } |
| 18206 | 18213 | |
| 18214 | static bool result_loc_is_discard(ResultLoc *result_loc_pass1) { |
| 18215 | if (result_loc_pass1->id == ResultLocIdInstruction && |
| 18216 | result_loc_pass1->source_instruction->id == IrInstSrcIdConst) |
| 18217 | { |
| 18218 | IrInstSrcConst *const_inst = reinterpret_cast<IrInstSrcConst *>(result_loc_pass1->source_instruction); |
| 18219 | if (value_is_comptime(const_inst->value) && |
| 18220 | const_inst->value->type->id == ZigTypeIdPointer && |
| 18221 | const_inst->value->data.x_ptr.special == ConstPtrSpecialDiscard) |
| 18222 | { |
| 18223 | return true; |
| 18224 | } |
| 18225 | } |
| 18226 | return false; |
| 18227 | } |
| 18228 | |
| 18207 | 18229 | // when calling this function, at the callsite must check for result type noreturn and propagate it up |
| 18208 | 18230 | static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr, |
| 18209 | 18231 | ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, |
| ... | ... | @@ -18494,13 +18516,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i |
| 18494 | 18516 | assert(parent_ptr_type->id == ZigTypeIdPointer); |
| 18495 | 18517 | ZigType *child_type = parent_ptr_type->data.pointer.child_type; |
| 18496 | 18518 | |
| 18497 | | bool has_bits; |
| 18498 | | if ((err = type_has_bits2(ira->codegen, child_type, &has_bits))) { |
| 18499 | | return ira->codegen->invalid_inst_gen; |
| 18500 | | } |
| 18501 | | |
| 18502 | | // This happens when the bitCast result is assigned to _ |
| 18503 | | if (!has_bits) { |
| 18519 | if (result_loc_is_discard(result_bit_cast->parent)) { |
| 18504 | 18520 | assert(allow_discard); |
| 18505 | 18521 | return parent_result_loc; |
| 18506 | 18522 | } |
| ... | ... | @@ -18531,16 +18547,8 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr |
| 18531 | 18547 | bool allow_discard) |
| 18532 | 18548 | { |
| 18533 | 18549 | Error err; |
| 18534 | | if (!allow_discard && result_loc_pass1->id == ResultLocIdInstruction && |
| 18535 | | result_loc_pass1->source_instruction->id == IrInstSrcIdConst) |
| 18536 | | { |
| 18537 | | IrInstSrcConst *const_inst = reinterpret_cast<IrInstSrcConst *>(result_loc_pass1->source_instruction); |
| 18538 | | if (value_is_comptime(const_inst->value) && |
| 18539 | | const_inst->value->type->id == ZigTypeIdPointer && |
| 18540 | | const_inst->value->data.x_ptr.special == ConstPtrSpecialDiscard) |
| 18541 | | { |
| 18542 | | result_loc_pass1 = no_result_loc(); |
| 18543 | | } |
| 18550 | if (!allow_discard && result_loc_is_discard(result_loc_pass1)) { |
| 18551 | result_loc_pass1 = no_result_loc(); |
| 18544 | 18552 | } |
| 18545 | 18553 | bool was_written = result_loc_pass1->written; |
| 18546 | 18554 | IrInstGen *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, |
| ... | ... | @@ -21062,7 +21070,7 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins |
| 21062 | 21070 | IrInstGen *elem = ir_const(ira, source_instr, field_type); |
| 21063 | 21071 | memoize_field_init_val(ira->codegen, struct_type, field); |
| 21064 | 21072 | copy_const_val(elem->value, field->init_val); |
| 21065 | | return ir_get_ref(ira, source_instr, elem, true, false); |
| 21073 | return ir_get_ref2(ira, source_instr, elem, field_type, true, false); |
| 21066 | 21074 | } |
| 21067 | 21075 | switch (type_has_one_possible_value(ira->codegen, field_type)) { |
| 21068 | 21076 | case OnePossibleValueInvalid: |
| ... | ... | @@ -27708,7 +27716,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn |
| 27708 | 27716 | if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) |
| 27709 | 27717 | return ira->codegen->invalid_inst_gen; |
| 27710 | 27718 | |
| 27711 | | if (type_has_bits(dest_type) && !type_has_bits(src_type)) { |
| 27719 | if (type_has_bits(dest_type) && !type_has_bits(src_type) && safety_check_on) { |
| 27712 | 27720 | ErrorMsg *msg = ir_add_error(ira, source_instr, |
| 27713 | 27721 | buf_sprintf("'%s' and '%s' do not have the same in-memory representation", |
| 27714 | 27722 | buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); |
| ... | ... | @@ -27723,7 +27731,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn |
| 27723 | 27731 | bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); |
| 27724 | 27732 | UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad; |
| 27725 | 27733 | ZigValue *val = ir_resolve_const(ira, ptr, is_undef_allowed); |
| 27726 | | if (!val) |
| 27734 | if (val == nullptr) |
| 27727 | 27735 | return ira->codegen->invalid_inst_gen; |
| 27728 | 27736 | |
| 27729 | 27737 | if (value_is_comptime(val) && val->special != ConstValSpecialUndef) { |
| ... | ... | @@ -27738,15 +27746,31 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn |
| 27738 | 27746 | } |
| 27739 | 27747 | |
| 27740 | 27748 | IrInstGen *result; |
| 27741 | | if (ptr->value->data.x_ptr.mut == ConstPtrMutInfer) { |
| 27749 | if (val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 27742 | 27750 | result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); |
| 27743 | | |
| 27744 | | if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) |
| 27745 | | return ira->codegen->invalid_inst_gen; |
| 27746 | 27751 | } else { |
| 27747 | 27752 | result = ir_const(ira, source_instr, dest_type); |
| 27748 | 27753 | } |
| 27749 | | copy_const_val(result->value, val); |
| 27754 | InferredStructField *isf = (val->type->id == ZigTypeIdPointer) ? |
| 27755 | val->type->data.pointer.inferred_struct_field : nullptr; |
| 27756 | if (isf == nullptr) { |
| 27757 | copy_const_val(result->value, val); |
| 27758 | } else { |
| 27759 | // The destination value should have x_ptr struct pointing to underlying struct value |
| 27760 | result->value->data.x_ptr.mut = val->data.x_ptr.mut; |
| 27761 | TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); |
| 27762 | assert(field != nullptr); |
| 27763 | if (field->is_comptime) { |
| 27764 | result->value->data.x_ptr.special = ConstPtrSpecialRef; |
| 27765 | result->value->data.x_ptr.data.ref.pointee = field->init_val; |
| 27766 | } else { |
| 27767 | assert(val->data.x_ptr.special == ConstPtrSpecialRef); |
| 27768 | result->value->data.x_ptr.special = ConstPtrSpecialBaseStruct; |
| 27769 | result->value->data.x_ptr.data.base_struct.struct_val = val->data.x_ptr.data.ref.pointee; |
| 27770 | result->value->data.x_ptr.data.base_struct.field_index = field->src_index; |
| 27771 | } |
| 27772 | result->value->special = ConstValSpecialStatic; |
| 27773 | } |
| 27750 | 27774 | result->value->type = dest_type; |
| 27751 | 27775 | |
| 27752 | 27776 | // Keep the bigger alignment, it can only help- |