| ... | ... | @@ -1951,12 +1951,14 @@ static IrInstruction *ir_build_widen_or_shorten(IrBuilder *irb, Scope *scope, As |
| 1951 | 1951 | } |
| 1952 | 1952 | |
| 1953 | 1953 | static IrInstruction *ir_build_int_to_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1954 | | IrInstruction *target) |
| 1954 | IrInstruction *dest_type, IrInstruction *target) |
| 1955 | 1955 | { |
| 1956 | 1956 | IrInstructionIntToPtr *instruction = ir_build_instruction<IrInstructionIntToPtr>( |
| 1957 | 1957 | irb, scope, source_node); |
| 1958 | instruction->dest_type = dest_type; |
| 1958 | 1959 | instruction->target = target; |
| 1959 | 1960 | |
| 1961 | if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); |
| 1960 | 1962 | ir_ref_instruction(target, irb->current_basic_block); |
| 1961 | 1963 | |
| 1962 | 1964 | return &instruction->base; |
| ... | ... | @@ -2185,8 +2187,8 @@ static IrInstruction *ir_instruction_binop_get_dep(IrInstructionBinOp *instructi |
| 2185 | 2187 | |
| 2186 | 2188 | static IrInstruction *ir_instruction_declvar_get_dep(IrInstructionDeclVar *instruction, size_t index) { |
| 2187 | 2189 | switch (index) { |
| 2188 | | case 0: return instruction->var_type; |
| 2189 | | case 1: return instruction->init_value; |
| 2190 | case 0: return instruction->init_value; |
| 2191 | case 1: return instruction->var_type; |
| 2190 | 2192 | default: return nullptr; |
| 2191 | 2193 | } |
| 2192 | 2194 | } |
| ... | ... | @@ -2670,8 +2672,8 @@ static IrInstruction *ir_instruction_ptrcast_get_dep(IrInstructionPtrCast *instr |
| 2670 | 2672 | size_t index) |
| 2671 | 2673 | { |
| 2672 | 2674 | switch (index) { |
| 2673 | | case 0: return instruction->dest_type; |
| 2674 | | case 1: return instruction->ptr; |
| 2675 | case 0: return instruction->ptr; |
| 2676 | case 1: return instruction->dest_type; |
| 2675 | 2677 | default: return nullptr; |
| 2676 | 2678 | } |
| 2677 | 2679 | } |
| ... | ... | @@ -2686,6 +2688,7 @@ static IrInstruction *ir_instruction_widenorshorten_get_dep(IrInstructionWidenOr |
| 2686 | 2688 | static IrInstruction *ir_instruction_inttoptr_get_dep(IrInstructionIntToPtr *instruction, size_t index) { |
| 2687 | 2689 | switch (index) { |
| 2688 | 2690 | case 0: return instruction->target; |
| 2691 | case 1: return instruction->dest_type; |
| 2689 | 2692 | default: return nullptr; |
| 2690 | 2693 | } |
| 2691 | 2694 | } |
| ... | ... | @@ -4222,6 +4225,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4222 | 4225 | |
| 4223 | 4226 | return ir_build_ptr_cast(irb, scope, node, arg0_value, arg1_value); |
| 4224 | 4227 | } |
| 4228 | case BuiltinFnIdIntToPtr: |
| 4229 | { |
| 4230 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 4231 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| 4232 | if (arg0_value == irb->codegen->invalid_instruction) |
| 4233 | return arg0_value; |
| 4234 | |
| 4235 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 4236 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); |
| 4237 | if (arg1_value == irb->codegen->invalid_instruction) |
| 4238 | return arg1_value; |
| 4239 | |
| 4240 | return ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value); |
| 4241 | } |
| 4225 | 4242 | } |
| 4226 | 4243 | zig_unreachable(); |
| 4227 | 4244 | } |
| ... | ... | @@ -5821,10 +5838,19 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 5821 | 5838 | } |
| 5822 | 5839 | |
| 5823 | 5840 | // implicit number literal to typed number |
| 5824 | | if ((actual_type->id == TypeTableEntryIdNumLitFloat || |
| 5825 | | actual_type->id == TypeTableEntryIdNumLitInt)) |
| 5841 | // implicit number literal to &const integer |
| 5842 | if (actual_type->id == TypeTableEntryIdNumLitFloat || |
| 5843 | actual_type->id == TypeTableEntryIdNumLitInt) |
| 5826 | 5844 | { |
| 5827 | | if (ir_num_lit_fits_in_other_type(ira, value, expected_type)) { |
| 5845 | if (expected_type->id == TypeTableEntryIdPointer && |
| 5846 | expected_type->data.pointer.is_const) |
| 5847 | { |
| 5848 | if (ir_num_lit_fits_in_other_type(ira, value, expected_type->data.pointer.child_type)) { |
| 5849 | return ImplicitCastMatchResultYes; |
| 5850 | } else { |
| 5851 | return ImplicitCastMatchResultReportedError; |
| 5852 | } |
| 5853 | } else if (ir_num_lit_fits_in_other_type(ira, value, expected_type)) { |
| 5828 | 5854 | return ImplicitCastMatchResultYes; |
| 5829 | 5855 | } else { |
| 5830 | 5856 | return ImplicitCastMatchResultReportedError; |
| ... | ... | @@ -6651,47 +6677,6 @@ static IrInstruction *ir_analyze_ptr_to_int(IrAnalyze *ira, IrInstruction *sourc |
| 6651 | 6677 | return result; |
| 6652 | 6678 | } |
| 6653 | 6679 | |
| 6654 | | static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| 6655 | | IrInstruction *target, TypeTableEntry *wanted_type) |
| 6656 | | { |
| 6657 | | assert(wanted_type->id == TypeTableEntryIdPointer); |
| 6658 | | |
| 6659 | | if (instr_is_comptime(target)) { |
| 6660 | | ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); |
| 6661 | | if (!val) |
| 6662 | | return ira->codegen->invalid_instruction; |
| 6663 | | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, |
| 6664 | | source_instr->source_node, wanted_type); |
| 6665 | | result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; |
| 6666 | | result->value.data.x_ptr.data.hard_coded_addr.addr = bignum_to_twos_complement(&val->data.x_bignum); |
| 6667 | | return result; |
| 6668 | | } |
| 6669 | | |
| 6670 | | IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, source_instr->scope, |
| 6671 | | source_instr->source_node, target); |
| 6672 | | result->value.type = wanted_type; |
| 6673 | | return result; |
| 6674 | | } |
| 6675 | | |
| 6676 | | static IrInstruction *ir_analyze_int_lit_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| 6677 | | IrInstruction *target, TypeTableEntry *wanted_type) |
| 6678 | | { |
| 6679 | | assert(wanted_type->id == TypeTableEntryIdPointer); |
| 6680 | | |
| 6681 | | ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); |
| 6682 | | if (!val) |
| 6683 | | return ira->codegen->invalid_instruction; |
| 6684 | | |
| 6685 | | TypeTableEntry *usize_type = ira->codegen->builtin_types.entry_usize; |
| 6686 | | if (!ir_num_lit_fits_in_other_type(ira, target, usize_type)) |
| 6687 | | return ira->codegen->invalid_instruction; |
| 6688 | | |
| 6689 | | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, |
| 6690 | | source_instr->source_node, wanted_type); |
| 6691 | | result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; |
| 6692 | | result->value.data.x_ptr.data.hard_coded_addr.addr = bignum_to_twos_complement(&val->data.x_bignum); |
| 6693 | | return result; |
| 6694 | | } |
| 6695 | 6680 | |
| 6696 | 6681 | static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *source_instr, |
| 6697 | 6682 | IrInstruction *target, TypeTableEntry *wanted_type) |
| ... | ... | @@ -6815,7 +6800,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 6815 | 6800 | TypeTableEntry *wanted_type_canon = get_underlying_type(wanted_type); |
| 6816 | 6801 | TypeTableEntry *actual_type_canon = get_underlying_type(actual_type); |
| 6817 | 6802 | |
| 6818 | | TypeTableEntry *isize_type = ira->codegen->builtin_types.entry_isize; |
| 6819 | 6803 | TypeTableEntry *usize_type = ira->codegen->builtin_types.entry_usize; |
| 6820 | 6804 | |
| 6821 | 6805 | if (type_is_invalid(wanted_type_canon) || type_is_invalid(actual_type_canon)) { |
| ... | ... | @@ -6837,28 +6821,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 6837 | 6821 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpBoolToInt, false); |
| 6838 | 6822 | } |
| 6839 | 6823 | |
| 6840 | | // explicit cast from pointer to isize or usize |
| 6841 | | if ((wanted_type_canon == isize_type || wanted_type_canon == usize_type) && |
| 6842 | | type_is_codegen_pointer(actual_type_canon)) |
| 6843 | | { |
| 6824 | // explicit cast from pointer to usize |
| 6825 | if (wanted_type_canon == usize_type && type_is_codegen_pointer(actual_type_canon)) { |
| 6844 | 6826 | return ir_analyze_ptr_to_int(ira, source_instr, value, wanted_type); |
| 6845 | 6827 | } |
| 6846 | 6828 | |
| 6847 | | |
| 6848 | | // explicit cast from isize or usize to pointer |
| 6849 | | if (wanted_type_canon->id == TypeTableEntryIdPointer && |
| 6850 | | (actual_type_canon == isize_type || actual_type_canon == usize_type)) |
| 6851 | | { |
| 6852 | | return ir_analyze_int_to_ptr(ira, source_instr, value, wanted_type); |
| 6853 | | } |
| 6854 | | |
| 6855 | | // explicit cast from number literal to pointer |
| 6856 | | if (wanted_type_canon->id == TypeTableEntryIdPointer && |
| 6857 | | (actual_type_canon->id == TypeTableEntryIdNumLitInt)) |
| 6858 | | { |
| 6859 | | return ir_analyze_int_lit_to_ptr(ira, source_instr, value, wanted_type); |
| 6860 | | } |
| 6861 | | |
| 6862 | 6829 | // explicit widening or shortening cast |
| 6863 | 6830 | if ((wanted_type_canon->id == TypeTableEntryIdInt && |
| 6864 | 6831 | actual_type_canon->id == TypeTableEntryIdInt) || |
| ... | ... | @@ -6970,10 +6937,23 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 6970 | 6937 | } |
| 6971 | 6938 | |
| 6972 | 6939 | // explicit cast from number literal to another type |
| 6940 | // explicit cast from number literal to &const integer |
| 6973 | 6941 | if (actual_type->id == TypeTableEntryIdNumLitFloat || |
| 6974 | 6942 | actual_type->id == TypeTableEntryIdNumLitInt) |
| 6975 | 6943 | { |
| 6976 | | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type_canon)) { |
| 6944 | if (wanted_type->id == TypeTableEntryIdPointer && |
| 6945 | wanted_type->data.pointer.is_const) |
| 6946 | { |
| 6947 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value); |
| 6948 | if (type_is_invalid(cast1->value.type)) |
| 6949 | return ira->codegen->invalid_instruction; |
| 6950 | |
| 6951 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); |
| 6952 | if (type_is_invalid(cast2->value.type)) |
| 6953 | return ira->codegen->invalid_instruction; |
| 6954 | |
| 6955 | return cast2; |
| 6956 | } else if (ir_num_lit_fits_in_other_type(ira, value, wanted_type_canon)) { |
| 6977 | 6957 | CastOp op; |
| 6978 | 6958 | if ((actual_type->id == TypeTableEntryIdNumLitFloat && |
| 6979 | 6959 | wanted_type_canon->id == TypeTableEntryIdFloat) || |
| ... | ... | @@ -12304,12 +12284,6 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio |
| 12304 | 12284 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 12305 | 12285 | } |
| 12306 | 12286 | |
| 12307 | | static bool is_ptr_type(TypeTableEntry *t) { |
| 12308 | | return (t->id == TypeTableEntryIdPointer || t->id == TypeTableEntryIdFn || |
| 12309 | | (t->id == TypeTableEntryIdMaybe && (t->data.maybe.child_type->id == TypeTableEntryIdPointer || |
| 12310 | | t->data.maybe.child_type->id == TypeTableEntryIdFn))); |
| 12311 | | } |
| 12312 | | |
| 12313 | 12287 | static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtrCast *instruction) { |
| 12314 | 12288 | IrInstruction *dest_type_value = instruction->dest_type->other; |
| 12315 | 12289 | TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value); |
| ... | ... | @@ -12321,12 +12295,12 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc |
| 12321 | 12295 | if (type_is_invalid(src_type)) |
| 12322 | 12296 | return ira->codegen->builtin_types.entry_invalid; |
| 12323 | 12297 | |
| 12324 | | if (!is_ptr_type(src_type)) { |
| 12298 | if (!type_is_codegen_pointer(src_type)) { |
| 12325 | 12299 | ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); |
| 12326 | 12300 | return ira->codegen->builtin_types.entry_invalid; |
| 12327 | 12301 | } |
| 12328 | 12302 | |
| 12329 | | if (!is_ptr_type(dest_type)) { |
| 12303 | if (!type_is_codegen_pointer(dest_type)) { |
| 12330 | 12304 | ir_add_error(ira, dest_type_value, |
| 12331 | 12305 | buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); |
| 12332 | 12306 | return ira->codegen->builtin_types.entry_invalid; |
| ... | ... | @@ -12350,6 +12324,42 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc |
| 12350 | 12324 | return dest_type; |
| 12351 | 12325 | } |
| 12352 | 12326 | |
| 12327 | static TypeTableEntry *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) { |
| 12328 | IrInstruction *dest_type_value = instruction->dest_type->other; |
| 12329 | TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value); |
| 12330 | if (type_is_invalid(dest_type)) |
| 12331 | return ira->codegen->builtin_types.entry_invalid; |
| 12332 | |
| 12333 | if (!type_is_codegen_pointer(dest_type)) { |
| 12334 | ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); |
| 12335 | return ira->codegen->builtin_types.entry_invalid; |
| 12336 | } |
| 12337 | |
| 12338 | IrInstruction *target = instruction->target->other; |
| 12339 | if (type_is_invalid(target->value.type)) |
| 12340 | return ira->codegen->builtin_types.entry_invalid; |
| 12341 | |
| 12342 | IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); |
| 12343 | if (type_is_invalid(casted_int->value.type)) |
| 12344 | return ira->codegen->builtin_types.entry_invalid; |
| 12345 | |
| 12346 | if (instr_is_comptime(casted_int)) { |
| 12347 | ConstExprValue *val = ir_resolve_const(ira, casted_int, UndefBad); |
| 12348 | if (!val) |
| 12349 | return ira->codegen->builtin_types.entry_invalid; |
| 12350 | |
| 12351 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 12352 | out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; |
| 12353 | out_val->data.x_ptr.data.hard_coded_addr.addr = bignum_to_twos_complement(&val->data.x_bignum); |
| 12354 | return dest_type; |
| 12355 | } |
| 12356 | |
| 12357 | IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, instruction->base.scope, |
| 12358 | instruction->base.source_node, nullptr, casted_int); |
| 12359 | ir_link_new_instruction(result, &instruction->base); |
| 12360 | return dest_type; |
| 12361 | } |
| 12362 | |
| 12353 | 12363 | static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira, |
| 12354 | 12364 | IrInstructionDeclRef *instruction) |
| 12355 | 12365 | { |
| ... | ... | @@ -12424,8 +12434,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 12424 | 12434 | switch (instruction->id) { |
| 12425 | 12435 | case IrInstructionIdInvalid: |
| 12426 | 12436 | case IrInstructionIdWidenOrShorten: |
| 12427 | | case IrInstructionIdIntToPtr: |
| 12428 | | case IrInstructionIdPtrToInt: |
| 12429 | 12437 | case IrInstructionIdIntToEnum: |
| 12430 | 12438 | case IrInstructionIdIntToErr: |
| 12431 | 12439 | case IrInstructionIdErrToInt: |
| ... | ... | @@ -12433,6 +12441,7 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 12433 | 12441 | case IrInstructionIdStructFieldPtr: |
| 12434 | 12442 | case IrInstructionIdEnumFieldPtr: |
| 12435 | 12443 | case IrInstructionIdInitEnum: |
| 12444 | case IrInstructionIdPtrToInt: |
| 12436 | 12445 | zig_unreachable(); |
| 12437 | 12446 | case IrInstructionIdReturn: |
| 12438 | 12447 | return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction); |
| ... | ... | @@ -12590,6 +12599,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 12590 | 12599 | return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); |
| 12591 | 12600 | case IrInstructionIdPtrCast: |
| 12592 | 12601 | return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCast *)instruction); |
| 12602 | case IrInstructionIdIntToPtr: |
| 12603 | return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); |
| 12593 | 12604 | case IrInstructionIdMaybeWrap: |
| 12594 | 12605 | case IrInstructionIdErrWrapCode: |
| 12595 | 12606 | case IrInstructionIdErrWrapPayload: |