| ... | @@ -880,7 +880,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte | ... | @@ -880,7 +880,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte |
| 880 | case ZigTypeIdComptimeFloat: | 880 | case ZigTypeIdComptimeFloat: |
| 881 | case ZigTypeIdComptimeInt: | 881 | case ZigTypeIdComptimeInt: |
| 882 | case ZigTypeIdEnumLiteral: | 882 | case ZigTypeIdEnumLiteral: |
| 883 | case ZigTypeIdPointer: | | |
| 884 | case ZigTypeIdUndefined: | 883 | case ZigTypeIdUndefined: |
| 885 | case ZigTypeIdNull: | 884 | case ZigTypeIdNull: |
| 886 | case ZigTypeIdBoundFn: | 885 | case ZigTypeIdBoundFn: |
| ... | @@ -889,6 +888,8 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte | ... | @@ -889,6 +888,8 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte |
| 889 | case ZigTypeIdAnyFrame: | 888 | case ZigTypeIdAnyFrame: |
| 890 | case ZigTypeIdFn: | 889 | case ZigTypeIdFn: |
| 891 | return true; | 890 | return true; |
| | 891 | case ZigTypeIdPointer: |
| | 892 | return expected->data.pointer.inferred_struct_field == actual->data.pointer.inferred_struct_field; |
| 892 | case ZigTypeIdFloat: | 893 | case ZigTypeIdFloat: |
| 893 | return expected->data.floating.bit_count == actual->data.floating.bit_count; | 894 | return expected->data.floating.bit_count == actual->data.floating.bit_count; |
| 894 | case ZigTypeIdInt: | 895 | case ZigTypeIdInt: |
| ... | @@ -7014,6 +7015,7 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod | ... | @@ -7014,6 +7015,7 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod |
| 7014 | ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1); | 7015 | ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1); |
| 7015 | result_loc_bit_cast->base.id = ResultLocIdBitCast; | 7016 | result_loc_bit_cast->base.id = ResultLocIdBitCast; |
| 7016 | result_loc_bit_cast->base.source_instruction = dest_type; | 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 | ir_ref_instruction(dest_type, irb->current_basic_block); | 7019 | ir_ref_instruction(dest_type, irb->current_basic_block); |
| 7018 | result_loc_bit_cast->parent = result_loc; | 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,32 +13599,31 @@ static IrInstGen *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInst *source_in |
| 13597 | return result; | 13599 | return result; |
| 13598 | } | 13600 | } |
| 13599 | | 13601 | |
| 13600 | static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, | 13602 | static IrInstGen *ir_get_ref2(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, |
| 13601 | bool is_const, bool is_volatile) | 13603 | ZigType *elem_type, bool is_const, bool is_volatile) |
| 13602 | { | 13604 | { |
| 13603 | Error err; | 13605 | Error err; |
| 13604 | | 13606 | |
| 13605 | if (type_is_invalid(value->value->type)) | 13607 | if (type_is_invalid(elem_type)) |
| 13606 | return ira->codegen->invalid_inst_gen; | 13608 | return ira->codegen->invalid_inst_gen; |
| 13607 | | 13609 | |
| 13608 | if (instr_is_comptime(value)) { | 13610 | if (instr_is_comptime(value)) { |
| 13609 | ZigValue *val = ir_resolve_const(ira, value, LazyOk); | 13611 | ZigValue *val = ir_resolve_const(ira, value, LazyOk); |
| 13610 | if (!val) | 13612 | if (!val) |
| 13611 | return ira->codegen->invalid_inst_gen; | 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 | ConstPtrMutComptimeConst, is_const, is_volatile, 0); | 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 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); | 13619 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 13618 | | 13620 | |
| 13619 | if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown))) | 13621 | if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown))) |
| 13620 | return ira->codegen->invalid_inst_gen; | 13622 | return ira->codegen->invalid_inst_gen; |
| 13621 | | 13623 | |
| 13622 | IrInstGen *result_loc; | 13624 | IrInstGen *result_loc; |
| 13623 | if (type_has_bits(ptr_type) && !handle_is_ptr(value->value->type)) { | 13625 | if (type_has_bits(ptr_type) && !handle_is_ptr(elem_type)) { |
| 13624 | result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value->type, | 13626 | result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), elem_type, nullptr, true, true); |
| 13625 | nullptr, true, true); | | |
| 13626 | } else { | 13627 | } else { |
| 13627 | result_loc = nullptr; | 13628 | result_loc = nullptr; |
| 13628 | } | 13629 | } |
| ... | @@ -13632,6 +13633,12 @@ static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstG | ... | @@ -13632,6 +13633,12 @@ static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstG |
| 13632 | return new_instruction; | 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 | static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, AstNode *source_node, ZigType *union_type) { | 13642 | static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, AstNode *source_node, ZigType *union_type) { |
| 13636 | assert(union_type->id == ZigTypeIdUnion); | 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,6 +18211,21 @@ static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_sourc |
| 18204 | return result_loc->resolved_loc; | 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 | // when calling this function, at the callsite must check for result type noreturn and propagate it up | 18229 | // when calling this function, at the callsite must check for result type noreturn and propagate it up |
| 18208 | static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr, | 18230 | static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr, |
| 18209 | ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, | 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,13 +18516,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i |
| 18494 | assert(parent_ptr_type->id == ZigTypeIdPointer); | 18516 | assert(parent_ptr_type->id == ZigTypeIdPointer); |
| 18495 | ZigType *child_type = parent_ptr_type->data.pointer.child_type; | 18517 | ZigType *child_type = parent_ptr_type->data.pointer.child_type; |
| 18496 | | 18518 | |
| 18497 | bool has_bits; | 18519 | if (result_loc_is_discard(result_bit_cast->parent)) { |
| 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) { | | |
| 18504 | assert(allow_discard); | 18520 | assert(allow_discard); |
| 18505 | return parent_result_loc; | 18521 | return parent_result_loc; |
| 18506 | } | 18522 | } |
| ... | @@ -18531,16 +18547,8 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr | ... | @@ -18531,16 +18547,8 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr |
| 18531 | bool allow_discard) | 18547 | bool allow_discard) |
| 18532 | { | 18548 | { |
| 18533 | Error err; | 18549 | Error err; |
| 18534 | if (!allow_discard && result_loc_pass1->id == ResultLocIdInstruction && | 18550 | if (!allow_discard && result_loc_is_discard(result_loc_pass1)) { |
| 18535 | result_loc_pass1->source_instruction->id == IrInstSrcIdConst) | 18551 | result_loc_pass1 = no_result_loc(); |
| 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 | } | | |
| 18544 | } | 18552 | } |
| 18545 | bool was_written = result_loc_pass1->written; | 18553 | bool was_written = result_loc_pass1->written; |
| 18546 | IrInstGen *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, | 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,7 +21070,7 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins |
| 21062 | IrInstGen *elem = ir_const(ira, source_instr, field_type); | 21070 | IrInstGen *elem = ir_const(ira, source_instr, field_type); |
| 21063 | memoize_field_init_val(ira->codegen, struct_type, field); | 21071 | memoize_field_init_val(ira->codegen, struct_type, field); |
| 21064 | copy_const_val(elem->value, field->init_val); | 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 | switch (type_has_one_possible_value(ira->codegen, field_type)) { | 21075 | switch (type_has_one_possible_value(ira->codegen, field_type)) { |
| 21068 | case OnePossibleValueInvalid: | 21076 | case OnePossibleValueInvalid: |
| ... | @@ -27708,7 +27716,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn | ... | @@ -27708,7 +27716,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn |
| 27708 | if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) | 27716 | if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) |
| 27709 | return ira->codegen->invalid_inst_gen; | 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 | ErrorMsg *msg = ir_add_error(ira, source_instr, | 27720 | ErrorMsg *msg = ir_add_error(ira, source_instr, |
| 27713 | buf_sprintf("'%s' and '%s' do not have the same in-memory representation", | 27721 | buf_sprintf("'%s' and '%s' do not have the same in-memory representation", |
| 27714 | buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); | 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,7 +27731,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn |
| 27723 | bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); | 27731 | bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); |
| 27724 | UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad; | 27732 | UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad; |
| 27725 | ZigValue *val = ir_resolve_const(ira, ptr, is_undef_allowed); | 27733 | ZigValue *val = ir_resolve_const(ira, ptr, is_undef_allowed); |
| 27726 | if (!val) | 27734 | if (val == nullptr) |
| 27727 | return ira->codegen->invalid_inst_gen; | 27735 | return ira->codegen->invalid_inst_gen; |
| 27728 | | 27736 | |
| 27729 | if (value_is_comptime(val) && val->special != ConstValSpecialUndef) { | 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,15 +27746,31 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn |
| 27738 | } | 27746 | } |
| 27739 | | 27747 | |
| 27740 | IrInstGen *result; | 27748 | IrInstGen *result; |
| 27741 | if (ptr->value->data.x_ptr.mut == ConstPtrMutInfer) { | 27749 | if (val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 27742 | result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); | 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 | } else { | 27751 | } else { |
| 27747 | result = ir_const(ira, source_instr, dest_type); | 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 | result->value->type = dest_type; | 27774 | result->value->type = dest_type; |
| 27751 | | 27775 | |
| 27752 | // Keep the bigger alignment, it can only help- | 27776 | // Keep the bigger alignment, it can only help- |