| ... | ... | @@ -169,6 +169,10 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un |
| 169 | 169 | static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs); |
| 170 | 170 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); |
| 171 | 171 | static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry); |
| 172 | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, |
| 173 | ZigType *ptr_type); |
| 174 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 175 | ZigType *dest_type); |
| 172 | 176 | |
| 173 | 177 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 174 | 178 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | ... | @@ -5019,10 +5023,23 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction * |
| 5019 | 5023 | return ir_build_ref(irb, scope, value->source_node, value, false, false); |
| 5020 | 5024 | } |
| 5021 | 5025 | |
| 5026 | static PtrLen star_token_to_ptr_len(TokenId token_id) { |
| 5027 | switch (token_id) { |
| 5028 | case TokenIdStar: |
| 5029 | case TokenIdStarStar: |
| 5030 | return PtrLenSingle; |
| 5031 | case TokenIdBracketStarBracket: |
| 5032 | return PtrLenUnknown; |
| 5033 | case TokenIdBracketStarCBracket: |
| 5034 | return PtrLenC; |
| 5035 | default: |
| 5036 | zig_unreachable(); |
| 5037 | } |
| 5038 | } |
| 5039 | |
| 5022 | 5040 | static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 5023 | 5041 | assert(node->type == NodeTypePointerType); |
| 5024 | | PtrLen ptr_len = (node->data.pointer_type.star_token->id == TokenIdStar || |
| 5025 | | node->data.pointer_type.star_token->id == TokenIdStarStar) ? PtrLenSingle : PtrLenUnknown; |
| 5042 | PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id); |
| 5026 | 5043 | bool is_const = node->data.pointer_type.is_const; |
| 5027 | 5044 | bool is_volatile = node->data.pointer_type.is_volatile; |
| 5028 | 5045 | AstNode *expr_node = node->data.pointer_type.op_expr; |
| ... | ... | @@ -8538,6 +8555,20 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 8538 | 8555 | } |
| 8539 | 8556 | } |
| 8540 | 8557 | } |
| 8558 | if (other_type->id == ZigTypeIdPointer && other_type->data.pointer.ptr_len == PtrLenC && const_val_is_int) { |
| 8559 | if (!bigint_fits_in_bits(&const_val->data.x_bigint, ira->codegen->pointer_size_bytes * 8, true) && |
| 8560 | !bigint_fits_in_bits(&const_val->data.x_bigint, ira->codegen->pointer_size_bytes * 8, false)) |
| 8561 | { |
| 8562 | Buf *val_buf = buf_alloc(); |
| 8563 | bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); |
| 8564 | |
| 8565 | ir_add_error(ira, instruction, |
| 8566 | buf_sprintf("integer value %s outside of pointer address range", |
| 8567 | buf_ptr(val_buf))); |
| 8568 | return false; |
| 8569 | } |
| 8570 | return true; |
| 8571 | } |
| 8541 | 8572 | |
| 8542 | 8573 | const char *num_lit_str; |
| 8543 | 8574 | Buf *val_buf = buf_alloc(); |
| ... | ... | @@ -10811,6 +10842,37 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction * |
| 10811 | 10842 | return ir_build_vector_to_array(ira, source_instr, vector, array_type); |
| 10812 | 10843 | } |
| 10813 | 10844 | |
| 10845 | static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| 10846 | IrInstruction *integer, ZigType *dest_type) |
| 10847 | { |
| 10848 | IrInstruction *unsigned_integer; |
| 10849 | if (instr_is_comptime(integer)) { |
| 10850 | unsigned_integer = integer; |
| 10851 | } else { |
| 10852 | assert(integer->value.type->id == ZigTypeIdInt); |
| 10853 | |
| 10854 | if (integer->value.type->data.integral.bit_count > |
| 10855 | ira->codegen->builtin_types.entry_usize->data.integral.bit_count) |
| 10856 | { |
| 10857 | ir_add_error(ira, source_instr, |
| 10858 | buf_sprintf("integer type too big for implicit @intToPtr to type '%s'", buf_ptr(&dest_type->name))); |
| 10859 | return ira->codegen->invalid_instruction; |
| 10860 | } |
| 10861 | |
| 10862 | if (integer->value.type->data.integral.is_signed) { |
| 10863 | ZigType *unsigned_int_type = get_int_type(ira->codegen, false, |
| 10864 | integer->value.type->data.integral.bit_count); |
| 10865 | unsigned_integer = ir_analyze_bit_cast(ira, source_instr, integer, unsigned_int_type); |
| 10866 | if (type_is_invalid(unsigned_integer->value.type)) |
| 10867 | return ira->codegen->invalid_instruction; |
| 10868 | } else { |
| 10869 | unsigned_integer = integer; |
| 10870 | } |
| 10871 | } |
| 10872 | |
| 10873 | return ir_analyze_int_to_ptr(ira, source_instr, unsigned_integer, dest_type); |
| 10874 | } |
| 10875 | |
| 10814 | 10876 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, |
| 10815 | 10877 | ZigType *wanted_type, IrInstruction *value) |
| 10816 | 10878 | { |
| ... | ... | @@ -11217,6 +11279,14 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11217 | 11279 | return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type); |
| 11218 | 11280 | } |
| 11219 | 11281 | |
| 11282 | // casting to C pointers |
| 11283 | if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC) { |
| 11284 | // cast from integer to C pointer |
| 11285 | if (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt) { |
| 11286 | return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type); |
| 11287 | } |
| 11288 | } |
| 11289 | |
| 11220 | 11290 | // cast from undefined to anything |
| 11221 | 11291 | if (actual_type->id == ZigTypeIdUndefined) { |
| 11222 | 11292 | return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); |
| ... | ... | @@ -20674,32 +20744,10 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 20674 | 20744 | zig_unreachable(); |
| 20675 | 20745 | } |
| 20676 | 20746 | |
| 20677 | | static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) { |
| 20678 | | Error err; |
| 20679 | | IrInstruction *dest_type_value = instruction->dest_type->child; |
| 20680 | | ZigType *dest_type = ir_resolve_type(ira, dest_type_value); |
| 20681 | | if (type_is_invalid(dest_type)) |
| 20682 | | return ira->codegen->invalid_instruction; |
| 20683 | | |
| 20684 | | IrInstruction *value = instruction->value->child; |
| 20685 | | ZigType *src_type = value->value.type; |
| 20686 | | if (type_is_invalid(src_type)) |
| 20687 | | return ira->codegen->invalid_instruction; |
| 20688 | | |
| 20689 | | if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown))) |
| 20690 | | return ira->codegen->invalid_instruction; |
| 20691 | | |
| 20692 | | if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown))) |
| 20693 | | return ira->codegen->invalid_instruction; |
| 20694 | | |
| 20695 | | if (get_codegen_ptr_type(src_type) != nullptr) { |
| 20696 | | ir_add_error(ira, value, |
| 20697 | | buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name))); |
| 20698 | | return ira->codegen->invalid_instruction; |
| 20699 | | } |
| 20700 | | |
| 20701 | | switch (src_type->id) { |
| 20747 | static bool type_can_bit_cast(ZigType *t) { |
| 20748 | switch (t->id) { |
| 20702 | 20749 | case ZigTypeIdInvalid: |
| 20750 | zig_unreachable(); |
| 20703 | 20751 | case ZigTypeIdMetaType: |
| 20704 | 20752 | case ZigTypeIdOpaque: |
| 20705 | 20753 | case ZigTypeIdBoundFn: |
| ... | ... | @@ -20710,42 +20758,36 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct |
| 20710 | 20758 | case ZigTypeIdComptimeInt: |
| 20711 | 20759 | case ZigTypeIdUndefined: |
| 20712 | 20760 | case ZigTypeIdNull: |
| 20713 | | ir_add_error(ira, dest_type_value, |
| 20714 | | buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name))); |
| 20715 | | return ira->codegen->invalid_instruction; |
| 20761 | case ZigTypeIdPointer: |
| 20762 | return false; |
| 20716 | 20763 | default: |
| 20717 | | break; |
| 20764 | // TODO list these types out explicitly, there are probably some other invalid ones here |
| 20765 | return true; |
| 20718 | 20766 | } |
| 20767 | } |
| 20719 | 20768 | |
| 20720 | | if (get_codegen_ptr_type(dest_type) != nullptr) { |
| 20721 | | ir_add_error(ira, dest_type_value, |
| 20722 | | buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); |
| 20769 | static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 20770 | ZigType *dest_type) |
| 20771 | { |
| 20772 | Error err; |
| 20773 | |
| 20774 | ZigType *src_type = value->value.type; |
| 20775 | assert(get_codegen_ptr_type(src_type) == nullptr); |
| 20776 | assert(type_can_bit_cast(src_type)); |
| 20777 | assert(get_codegen_ptr_type(dest_type) == nullptr); |
| 20778 | assert(type_can_bit_cast(dest_type)); |
| 20779 | |
| 20780 | if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown))) |
| 20781 | return ira->codegen->invalid_instruction; |
| 20782 | |
| 20783 | if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown))) |
| 20723 | 20784 | return ira->codegen->invalid_instruction; |
| 20724 | | } |
| 20725 | 20785 | |
| 20726 | | switch (dest_type->id) { |
| 20727 | | case ZigTypeIdInvalid: |
| 20728 | | case ZigTypeIdMetaType: |
| 20729 | | case ZigTypeIdOpaque: |
| 20730 | | case ZigTypeIdBoundFn: |
| 20731 | | case ZigTypeIdArgTuple: |
| 20732 | | case ZigTypeIdNamespace: |
| 20733 | | case ZigTypeIdUnreachable: |
| 20734 | | case ZigTypeIdComptimeFloat: |
| 20735 | | case ZigTypeIdComptimeInt: |
| 20736 | | case ZigTypeIdUndefined: |
| 20737 | | case ZigTypeIdNull: |
| 20738 | | ir_add_error(ira, dest_type_value, |
| 20739 | | buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); |
| 20740 | | return ira->codegen->invalid_instruction; |
| 20741 | | default: |
| 20742 | | break; |
| 20743 | | } |
| 20744 | 20786 | |
| 20745 | 20787 | uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); |
| 20746 | 20788 | uint64_t src_size_bytes = type_size(ira->codegen, src_type); |
| 20747 | 20789 | if (dest_size_bytes != src_size_bytes) { |
| 20748 | | ir_add_error(ira, &instruction->base, |
| 20790 | ir_add_error(ira, source_instr, |
| 20749 | 20791 | buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64, |
| 20750 | 20792 | buf_ptr(&dest_type->name), dest_size_bytes, |
| 20751 | 20793 | buf_ptr(&src_type->name), src_size_bytes)); |
| ... | ... | @@ -20755,7 +20797,7 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct |
| 20755 | 20797 | uint64_t dest_size_bits = type_size_bits(ira->codegen, dest_type); |
| 20756 | 20798 | uint64_t src_size_bits = type_size_bits(ira->codegen, src_type); |
| 20757 | 20799 | if (dest_size_bits != src_size_bits) { |
| 20758 | | ir_add_error(ira, &instruction->base, |
| 20800 | ir_add_error(ira, source_instr, |
| 20759 | 20801 | buf_sprintf("destination type '%s' has %" ZIG_PRI_u64 " bits but source type '%s' has %" ZIG_PRI_u64 " bits", |
| 20760 | 20802 | buf_ptr(&dest_type->name), dest_size_bits, |
| 20761 | 20803 | buf_ptr(&src_type->name), src_size_bits)); |
| ... | ... | @@ -20767,44 +20809,63 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct |
| 20767 | 20809 | if (!val) |
| 20768 | 20810 | return ira->codegen->invalid_instruction; |
| 20769 | 20811 | |
| 20770 | | IrInstruction *result = ir_const(ira, &instruction->base, dest_type); |
| 20812 | IrInstruction *result = ir_const(ira, source_instr, dest_type); |
| 20771 | 20813 | uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes); |
| 20772 | 20814 | buf_write_value_bytes(ira->codegen, buf, val); |
| 20773 | | if ((err = buf_read_value_bytes(ira, ira->codegen, instruction->base.source_node, buf, &result->value))) |
| 20815 | if ((err = buf_read_value_bytes(ira, ira->codegen, source_instr->source_node, buf, &result->value))) |
| 20774 | 20816 | return ira->codegen->invalid_instruction; |
| 20775 | 20817 | return result; |
| 20776 | 20818 | } |
| 20777 | 20819 | |
| 20778 | | IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope, |
| 20779 | | instruction->base.source_node, nullptr, value); |
| 20820 | IrInstruction *result = ir_build_bit_cast(&ira->new_irb, source_instr->scope, |
| 20821 | source_instr->source_node, nullptr, value); |
| 20780 | 20822 | result->value.type = dest_type; |
| 20781 | 20823 | return result; |
| 20782 | 20824 | } |
| 20783 | 20825 | |
| 20784 | | static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) { |
| 20785 | | Error err; |
| 20826 | static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) { |
| 20786 | 20827 | IrInstruction *dest_type_value = instruction->dest_type->child; |
| 20787 | 20828 | ZigType *dest_type = ir_resolve_type(ira, dest_type_value); |
| 20788 | 20829 | if (type_is_invalid(dest_type)) |
| 20789 | 20830 | return ira->codegen->invalid_instruction; |
| 20790 | 20831 | |
| 20791 | | // We explicitly check for the size, so we can use get_src_ptr_type |
| 20792 | | if (get_src_ptr_type(dest_type) == nullptr) { |
| 20793 | | ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); |
| 20832 | IrInstruction *value = instruction->value->child; |
| 20833 | ZigType *src_type = value->value.type; |
| 20834 | if (type_is_invalid(src_type)) |
| 20835 | return ira->codegen->invalid_instruction; |
| 20836 | |
| 20837 | if (get_codegen_ptr_type(src_type) != nullptr) { |
| 20838 | ir_add_error(ira, value, |
| 20839 | buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name))); |
| 20794 | 20840 | return ira->codegen->invalid_instruction; |
| 20795 | 20841 | } |
| 20796 | 20842 | |
| 20797 | | if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) |
| 20843 | if (!type_can_bit_cast(src_type)) { |
| 20844 | ir_add_error(ira, dest_type_value, |
| 20845 | buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name))); |
| 20798 | 20846 | return ira->codegen->invalid_instruction; |
| 20799 | | if (!type_has_bits(dest_type)) { |
| 20847 | } |
| 20848 | |
| 20849 | if (get_codegen_ptr_type(dest_type) != nullptr) { |
| 20800 | 20850 | ir_add_error(ira, dest_type_value, |
| 20801 | | buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name))); |
| 20851 | buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); |
| 20802 | 20852 | return ira->codegen->invalid_instruction; |
| 20803 | 20853 | } |
| 20804 | 20854 | |
| 20805 | | IrInstruction *target = instruction->target->child; |
| 20806 | | if (type_is_invalid(target->value.type)) |
| 20855 | if (!type_can_bit_cast(dest_type)) { |
| 20856 | ir_add_error(ira, dest_type_value, |
| 20857 | buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); |
| 20807 | 20858 | return ira->codegen->invalid_instruction; |
| 20859 | } |
| 20860 | |
| 20861 | return ir_analyze_bit_cast(ira, &instruction->base, value, dest_type); |
| 20862 | } |
| 20863 | |
| 20864 | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, |
| 20865 | ZigType *ptr_type) |
| 20866 | { |
| 20867 | assert(get_src_ptr_type(ptr_type) != nullptr); |
| 20868 | assert(type_has_bits(ptr_type)); |
| 20808 | 20869 | |
| 20809 | 20870 | IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); |
| 20810 | 20871 | if (type_is_invalid(casted_int->value.type)) |
| ... | ... | @@ -20815,19 +20876,48 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru |
| 20815 | 20876 | if (!val) |
| 20816 | 20877 | return ira->codegen->invalid_instruction; |
| 20817 | 20878 | |
| 20818 | | IrInstruction *result = ir_const(ira, &instruction->base, dest_type); |
| 20879 | IrInstruction *result = ir_const(ira, source_instr, ptr_type); |
| 20819 | 20880 | result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; |
| 20820 | 20881 | result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar; |
| 20821 | 20882 | result->value.data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&val->data.x_bigint); |
| 20822 | 20883 | return result; |
| 20823 | 20884 | } |
| 20824 | 20885 | |
| 20825 | | IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, instruction->base.scope, |
| 20826 | | instruction->base.source_node, nullptr, casted_int); |
| 20827 | | result->value.type = dest_type; |
| 20886 | IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, source_instr->scope, |
| 20887 | source_instr->source_node, nullptr, casted_int); |
| 20888 | result->value.type = ptr_type; |
| 20828 | 20889 | return result; |
| 20829 | 20890 | } |
| 20830 | 20891 | |
| 20892 | static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) { |
| 20893 | Error err; |
| 20894 | IrInstruction *dest_type_value = instruction->dest_type->child; |
| 20895 | ZigType *dest_type = ir_resolve_type(ira, dest_type_value); |
| 20896 | if (type_is_invalid(dest_type)) |
| 20897 | return ira->codegen->invalid_instruction; |
| 20898 | |
| 20899 | // We explicitly check for the size, so we can use get_src_ptr_type |
| 20900 | if (get_src_ptr_type(dest_type) == nullptr) { |
| 20901 | ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); |
| 20902 | return ira->codegen->invalid_instruction; |
| 20903 | } |
| 20904 | |
| 20905 | if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) |
| 20906 | return ira->codegen->invalid_instruction; |
| 20907 | if (!type_has_bits(dest_type)) { |
| 20908 | ir_add_error(ira, dest_type_value, |
| 20909 | buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name))); |
| 20910 | return ira->codegen->invalid_instruction; |
| 20911 | } |
| 20912 | |
| 20913 | |
| 20914 | IrInstruction *target = instruction->target->child; |
| 20915 | if (type_is_invalid(target->value.type)) |
| 20916 | return ira->codegen->invalid_instruction; |
| 20917 | |
| 20918 | return ir_analyze_int_to_ptr(ira, &instruction->base, target, dest_type); |
| 20919 | } |
| 20920 | |
| 20831 | 20921 | static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, |
| 20832 | 20922 | IrInstructionDeclRef *instruction) |
| 20833 | 20923 | { |