| ... | ... | @@ -138,6 +138,11 @@ struct ConstCastErrSetMismatch { |
| 138 | 138 | ZigList<ErrorTableEntry *> missing_errors; |
| 139 | 139 | }; |
| 140 | 140 | |
| 141 | enum UndefAllowed { |
| 142 | UndefOk, |
| 143 | UndefBad, |
| 144 | }; |
| 145 | |
| 141 | 146 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| 142 | 147 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval); |
| 143 | 148 | static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); |
| ... | ... | @@ -157,6 +162,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, |
| 157 | 162 | ConstExprValue *out_val, ConstExprValue *ptr_val); |
| 158 | 163 | static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, |
| 159 | 164 | ZigType *dest_type, IrInstruction *dest_type_src); |
| 165 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); |
| 160 | 166 | |
| 161 | 167 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 162 | 168 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | ... | @@ -8063,15 +8069,153 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 8063 | 8069 | return false; |
| 8064 | 8070 | } |
| 8065 | 8071 | |
| 8066 | | ConstExprValue *const_val = &instruction->value; |
| 8067 | | assert(const_val->special != ConstValSpecialRuntime); |
| 8072 | ConstExprValue *const_val = ir_resolve_const(ira, instruction, UndefBad); |
| 8073 | assert(const_val != nullptr); |
| 8074 | |
| 8075 | bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt); |
| 8076 | bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); |
| 8068 | 8077 | |
| 8069 | | bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || |
| 8070 | | const_val->type->id == ZigTypeIdComptimeInt); |
| 8071 | | bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || |
| 8072 | | const_val->type->id == ZigTypeIdComptimeFloat); |
| 8073 | 8078 | if (other_type->id == ZigTypeIdFloat) { |
| 8074 | | return true; |
| 8079 | if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) { |
| 8080 | return true; |
| 8081 | } |
| 8082 | if (const_val->type->id == ZigTypeIdInt) { |
| 8083 | BigFloat tmp_bf; |
| 8084 | bigfloat_init_bigint(&tmp_bf, &const_val->data.x_bigint); |
| 8085 | BigFloat orig_bf; |
| 8086 | switch (other_type->data.floating.bit_count) { |
| 8087 | case 16: { |
| 8088 | float16_t tmp = bigfloat_to_f16(&tmp_bf); |
| 8089 | bigfloat_init_16(&orig_bf, tmp); |
| 8090 | break; |
| 8091 | } |
| 8092 | case 32: { |
| 8093 | float tmp = bigfloat_to_f32(&tmp_bf); |
| 8094 | bigfloat_init_32(&orig_bf, tmp); |
| 8095 | break; |
| 8096 | } |
| 8097 | case 64: { |
| 8098 | double tmp = bigfloat_to_f64(&tmp_bf); |
| 8099 | bigfloat_init_64(&orig_bf, tmp); |
| 8100 | break; |
| 8101 | } |
| 8102 | case 80: |
| 8103 | zig_panic("TODO"); |
| 8104 | case 128: { |
| 8105 | float128_t tmp = bigfloat_to_f128(&tmp_bf); |
| 8106 | bigfloat_init_128(&orig_bf, tmp); |
| 8107 | break; |
| 8108 | } |
| 8109 | default: |
| 8110 | zig_unreachable(); |
| 8111 | } |
| 8112 | BigInt orig_bi; |
| 8113 | bigint_init_bigfloat(&orig_bi, &orig_bf); |
| 8114 | if (bigint_cmp(&orig_bi, &const_val->data.x_bigint) == CmpEQ) { |
| 8115 | return true; |
| 8116 | } |
| 8117 | Buf *val_buf = buf_alloc(); |
| 8118 | bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); |
| 8119 | ir_add_error(ira, instruction, |
| 8120 | buf_sprintf("integer value %s has no representation in type '%s'", |
| 8121 | buf_ptr(val_buf), |
| 8122 | buf_ptr(&other_type->name))); |
| 8123 | return false; |
| 8124 | } |
| 8125 | if (other_type->data.floating.bit_count >= const_val->type->data.floating.bit_count) { |
| 8126 | return true; |
| 8127 | } |
| 8128 | switch (other_type->data.floating.bit_count) { |
| 8129 | case 16: |
| 8130 | switch (const_val->type->data.floating.bit_count) { |
| 8131 | case 32: { |
| 8132 | float16_t tmp = zig_double_to_f16(const_val->data.x_f32); |
| 8133 | float orig = zig_f16_to_double(tmp); |
| 8134 | if (const_val->data.x_f32 == orig) { |
| 8135 | return true; |
| 8136 | } |
| 8137 | break; |
| 8138 | } |
| 8139 | case 64: { |
| 8140 | float16_t tmp = zig_double_to_f16(const_val->data.x_f64); |
| 8141 | double orig = zig_f16_to_double(tmp); |
| 8142 | if (const_val->data.x_f64 == orig) { |
| 8143 | return true; |
| 8144 | } |
| 8145 | break; |
| 8146 | } |
| 8147 | case 80: |
| 8148 | zig_panic("TODO"); |
| 8149 | case 128: { |
| 8150 | float16_t tmp = f128M_to_f16(&const_val->data.x_f128); |
| 8151 | float128_t orig; |
| 8152 | f16_to_f128M(tmp, &orig); |
| 8153 | if (f128M_eq(&orig, &const_val->data.x_f128)) { |
| 8154 | return true; |
| 8155 | } |
| 8156 | break; |
| 8157 | } |
| 8158 | default: |
| 8159 | zig_unreachable(); |
| 8160 | } |
| 8161 | break; |
| 8162 | case 32: |
| 8163 | switch (const_val->type->data.floating.bit_count) { |
| 8164 | case 64: { |
| 8165 | float tmp = const_val->data.x_f64; |
| 8166 | double orig = tmp; |
| 8167 | if (const_val->data.x_f64 == orig) { |
| 8168 | return true; |
| 8169 | } |
| 8170 | break; |
| 8171 | } |
| 8172 | case 80: |
| 8173 | zig_panic("TODO"); |
| 8174 | case 128: { |
| 8175 | float32_t tmp = f128M_to_f32(&const_val->data.x_f128); |
| 8176 | float128_t orig; |
| 8177 | f32_to_f128M(tmp, &orig); |
| 8178 | if (f128M_eq(&orig, &const_val->data.x_f128)) { |
| 8179 | return true; |
| 8180 | } |
| 8181 | break; |
| 8182 | } |
| 8183 | default: |
| 8184 | zig_unreachable(); |
| 8185 | } |
| 8186 | break; |
| 8187 | case 64: |
| 8188 | switch (const_val->type->data.floating.bit_count) { |
| 8189 | case 80: |
| 8190 | zig_panic("TODO"); |
| 8191 | case 128: { |
| 8192 | float64_t tmp = f128M_to_f64(&const_val->data.x_f128); |
| 8193 | float128_t orig; |
| 8194 | f64_to_f128M(tmp, &orig); |
| 8195 | if (f128M_eq(&orig, &const_val->data.x_f128)) { |
| 8196 | return true; |
| 8197 | } |
| 8198 | break; |
| 8199 | } |
| 8200 | default: |
| 8201 | zig_unreachable(); |
| 8202 | } |
| 8203 | break; |
| 8204 | case 80: |
| 8205 | assert(const_val->type->data.floating.bit_count == 128); |
| 8206 | zig_panic("TODO"); |
| 8207 | case 128: |
| 8208 | return true; |
| 8209 | default: |
| 8210 | zig_unreachable(); |
| 8211 | } |
| 8212 | Buf *val_buf = buf_alloc(); |
| 8213 | float_append_buf(val_buf, const_val); |
| 8214 | ir_add_error(ira, instruction, |
| 8215 | buf_sprintf("cast of value %s to type '%s' loses information", |
| 8216 | buf_ptr(val_buf), |
| 8217 | buf_ptr(&other_type->name))); |
| 8218 | return false; |
| 8075 | 8219 | } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { |
| 8076 | 8220 | if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { |
| 8077 | 8221 | Buf *val_buf = buf_alloc(); |
| ... | ... | @@ -9453,11 +9597,6 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio |
| 9453 | 9597 | return const_instr; |
| 9454 | 9598 | } |
| 9455 | 9599 | |
| 9456 | | enum UndefAllowed { |
| 9457 | | UndefOk, |
| 9458 | | UndefBad, |
| 9459 | | }; |
| 9460 | | |
| 9461 | 9600 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { |
| 9462 | 9601 | switch (value->value.special) { |
| 9463 | 9602 | case ConstValSpecialStatic: |
| ... | ... | @@ -10370,6 +10509,121 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10370 | 10509 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); |
| 10371 | 10510 | } |
| 10372 | 10511 | |
| 10512 | // cast from T to ?T |
| 10513 | // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism |
| 10514 | if (wanted_type->id == ZigTypeIdOptional) { |
| 10515 | ZigType *wanted_child_type = wanted_type->data.maybe.child_type; |
| 10516 | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, |
| 10517 | false).id == ConstCastResultIdOk) |
| 10518 | { |
| 10519 | return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); |
| 10520 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 10521 | actual_type->id == ZigTypeIdComptimeFloat) |
| 10522 | { |
| 10523 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { |
| 10524 | return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); |
| 10525 | } else { |
| 10526 | return ira->codegen->invalid_instruction; |
| 10527 | } |
| 10528 | } else if ( |
| 10529 | wanted_child_type->id == ZigTypeIdPointer && |
| 10530 | wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && |
| 10531 | actual_type->id == ZigTypeIdPointer && |
| 10532 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| 10533 | actual_type->data.pointer.child_type->id == ZigTypeIdArray) |
| 10534 | { |
| 10535 | if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) |
| 10536 | return ira->codegen->invalid_instruction; |
| 10537 | if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) |
| 10538 | return ira->codegen->invalid_instruction; |
| 10539 | if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && |
| 10540 | types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, |
| 10541 | actual_type->data.pointer.child_type->data.array.child_type, source_node, |
| 10542 | !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) |
| 10543 | { |
| 10544 | IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, |
| 10545 | wanted_child_type); |
| 10546 | if (type_is_invalid(cast1->value.type)) |
| 10547 | return ira->codegen->invalid_instruction; |
| 10548 | return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type); |
| 10549 | } |
| 10550 | } |
| 10551 | } |
| 10552 | |
| 10553 | // T to E!T |
| 10554 | if (wanted_type->id == ZigTypeIdErrorUnion) { |
| 10555 | if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, |
| 10556 | source_node, false).id == ConstCastResultIdOk) |
| 10557 | { |
| 10558 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| 10559 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 10560 | actual_type->id == ZigTypeIdComptimeFloat) |
| 10561 | { |
| 10562 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { |
| 10563 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| 10564 | } else { |
| 10565 | return ira->codegen->invalid_instruction; |
| 10566 | } |
| 10567 | } |
| 10568 | } |
| 10569 | |
| 10570 | // cast from T to E!?T |
| 10571 | if (wanted_type->id == ZigTypeIdErrorUnion && |
| 10572 | wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && |
| 10573 | actual_type->id != ZigTypeIdOptional) |
| 10574 | { |
| 10575 | ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; |
| 10576 | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || |
| 10577 | actual_type->id == ZigTypeIdNull || |
| 10578 | actual_type->id == ZigTypeIdComptimeInt || |
| 10579 | actual_type->id == ZigTypeIdComptimeFloat) |
| 10580 | { |
| 10581 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); |
| 10582 | if (type_is_invalid(cast1->value.type)) |
| 10583 | return ira->codegen->invalid_instruction; |
| 10584 | |
| 10585 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); |
| 10586 | if (type_is_invalid(cast2->value.type)) |
| 10587 | return ira->codegen->invalid_instruction; |
| 10588 | |
| 10589 | return cast2; |
| 10590 | } |
| 10591 | } |
| 10592 | |
| 10593 | |
| 10594 | // cast from comptime-known number to another number type |
| 10595 | if (instr_is_comptime(value) && |
| 10596 | (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt || |
| 10597 | actual_type->id == ZigTypeIdFloat || actual_type->id == ZigTypeIdComptimeFloat) && |
| 10598 | (wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdComptimeInt || |
| 10599 | wanted_type->id == ZigTypeIdFloat || wanted_type->id == ZigTypeIdComptimeFloat)) |
| 10600 | { |
| 10601 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { |
| 10602 | if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { |
| 10603 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); |
| 10604 | if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { |
| 10605 | bigint_init_bigint(&result->value.data.x_bigint, &value->value.data.x_bigint); |
| 10606 | } else { |
| 10607 | float_init_bigint(&result->value.data.x_bigint, &value->value); |
| 10608 | } |
| 10609 | return result; |
| 10610 | } else if (wanted_type->id == ZigTypeIdComptimeFloat || wanted_type->id == ZigTypeIdFloat) { |
| 10611 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); |
| 10612 | if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { |
| 10613 | BigFloat bf; |
| 10614 | bigfloat_init_bigint(&bf, &value->value.data.x_bigint); |
| 10615 | float_init_bigfloat(&result->value, &bf); |
| 10616 | } else { |
| 10617 | float_init_float(&result->value, &value->value); |
| 10618 | } |
| 10619 | return result; |
| 10620 | } |
| 10621 | zig_unreachable(); |
| 10622 | } else { |
| 10623 | return ira->codegen->invalid_instruction; |
| 10624 | } |
| 10625 | } |
| 10626 | |
| 10373 | 10627 | // widening conversion |
| 10374 | 10628 | if (wanted_type->id == ZigTypeIdInt && |
| 10375 | 10629 | actual_type->id == ZigTypeIdInt && |
| ... | ... | @@ -10472,47 +10726,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10472 | 10726 | } |
| 10473 | 10727 | |
| 10474 | 10728 | |
| 10475 | | // cast from T to ?T |
| 10476 | | // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism |
| 10477 | | if (wanted_type->id == ZigTypeIdOptional) { |
| 10478 | | ZigType *wanted_child_type = wanted_type->data.maybe.child_type; |
| 10479 | | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, |
| 10480 | | false).id == ConstCastResultIdOk) |
| 10481 | | { |
| 10482 | | return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); |
| 10483 | | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 10484 | | actual_type->id == ZigTypeIdComptimeFloat) |
| 10485 | | { |
| 10486 | | if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { |
| 10487 | | return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); |
| 10488 | | } else { |
| 10489 | | return ira->codegen->invalid_instruction; |
| 10490 | | } |
| 10491 | | } else if ( |
| 10492 | | wanted_child_type->id == ZigTypeIdPointer && |
| 10493 | | wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && |
| 10494 | | actual_type->id == ZigTypeIdPointer && |
| 10495 | | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| 10496 | | actual_type->data.pointer.child_type->id == ZigTypeIdArray) |
| 10497 | | { |
| 10498 | | if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) |
| 10499 | | return ira->codegen->invalid_instruction; |
| 10500 | | if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) |
| 10501 | | return ira->codegen->invalid_instruction; |
| 10502 | | if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && |
| 10503 | | types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, |
| 10504 | | actual_type->data.pointer.child_type->data.array.child_type, source_node, |
| 10505 | | !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) |
| 10506 | | { |
| 10507 | | IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, |
| 10508 | | wanted_child_type); |
| 10509 | | if (type_is_invalid(cast1->value.type)) |
| 10510 | | return ira->codegen->invalid_instruction; |
| 10511 | | return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type); |
| 10512 | | } |
| 10513 | | } |
| 10514 | | } |
| 10515 | | |
| 10516 | 10729 | // cast from null literal to maybe type |
| 10517 | 10730 | if (wanted_type->id == ZigTypeIdOptional && |
| 10518 | 10731 | actual_type->id == ZigTypeIdNull) |
| ... | ... | @@ -10520,23 +10733,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10520 | 10733 | return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); |
| 10521 | 10734 | } |
| 10522 | 10735 | |
| 10523 | | // cast from child type of error type to error type |
| 10524 | | if (wanted_type->id == ZigTypeIdErrorUnion) { |
| 10525 | | if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, |
| 10526 | | source_node, false).id == ConstCastResultIdOk) |
| 10527 | | { |
| 10528 | | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| 10529 | | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| 10530 | | actual_type->id == ZigTypeIdComptimeFloat) |
| 10531 | | { |
| 10532 | | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { |
| 10533 | | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| 10534 | | } else { |
| 10535 | | return ira->codegen->invalid_instruction; |
| 10536 | | } |
| 10537 | | } |
| 10538 | | } |
| 10539 | | |
| 10540 | 10736 | // cast from [N]T to E![]const T |
| 10541 | 10737 | if (wanted_type->id == ZigTypeIdErrorUnion && |
| 10542 | 10738 | is_slice(wanted_type->data.error_union.payload_type) && |
| ... | ... | @@ -10568,54 +10764,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10568 | 10764 | return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type); |
| 10569 | 10765 | } |
| 10570 | 10766 | |
| 10571 | | // cast from T to E!?T |
| 10572 | | if (wanted_type->id == ZigTypeIdErrorUnion && |
| 10573 | | wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && |
| 10574 | | actual_type->id != ZigTypeIdOptional) |
| 10575 | | { |
| 10576 | | ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; |
| 10577 | | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || |
| 10578 | | actual_type->id == ZigTypeIdNull || |
| 10579 | | actual_type->id == ZigTypeIdComptimeInt || |
| 10580 | | actual_type->id == ZigTypeIdComptimeFloat) |
| 10581 | | { |
| 10582 | | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); |
| 10583 | | if (type_is_invalid(cast1->value.type)) |
| 10584 | | return ira->codegen->invalid_instruction; |
| 10585 | | |
| 10586 | | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); |
| 10587 | | if (type_is_invalid(cast2->value.type)) |
| 10588 | | return ira->codegen->invalid_instruction; |
| 10589 | | |
| 10590 | | return cast2; |
| 10591 | | } |
| 10592 | | } |
| 10593 | | |
| 10594 | | // cast from number literal to another type |
| 10595 | | if (actual_type->id == ZigTypeIdComptimeFloat || |
| 10596 | | actual_type->id == ZigTypeIdComptimeInt) |
| 10597 | | { |
| 10598 | | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { |
| 10599 | | CastOp op; |
| 10600 | | if ((actual_type->id == ZigTypeIdComptimeFloat && |
| 10601 | | wanted_type->id == ZigTypeIdFloat) || |
| 10602 | | (actual_type->id == ZigTypeIdComptimeInt && |
| 10603 | | wanted_type->id == ZigTypeIdInt)) |
| 10604 | | { |
| 10605 | | op = CastOpNumLitToConcrete; |
| 10606 | | } else if (wanted_type->id == ZigTypeIdInt) { |
| 10607 | | op = CastOpFloatToInt; |
| 10608 | | } else if (wanted_type->id == ZigTypeIdFloat) { |
| 10609 | | op = CastOpIntToFloat; |
| 10610 | | } else { |
| 10611 | | zig_unreachable(); |
| 10612 | | } |
| 10613 | | return ir_resolve_cast(ira, source_instr, value, wanted_type, op, false); |
| 10614 | | } else { |
| 10615 | | return ira->codegen->invalid_instruction; |
| 10616 | | } |
| 10617 | | } |
| 10618 | | |
| 10619 | 10767 | // cast from typed number to integer or float literal. |
| 10620 | 10768 | // works when the number is known at compile time |
| 10621 | 10769 | if (instr_is_comptime(value) && |
| ... | ... | @@ -17878,7 +18026,7 @@ static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstruct |
| 17878 | 18026 | if (type_is_invalid(dest_type)) |
| 17879 | 18027 | return ira->codegen->invalid_instruction; |
| 17880 | 18028 | |
| 17881 | | if (dest_type->id != ZigTypeIdInt) { |
| 18029 | if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { |
| 17882 | 18030 | ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); |
| 17883 | 18031 | return ira->codegen->invalid_instruction; |
| 17884 | 18032 | } |
| ... | ... | @@ -17887,20 +18035,22 @@ static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstruct |
| 17887 | 18035 | if (type_is_invalid(target->value.type)) |
| 17888 | 18036 | return ira->codegen->invalid_instruction; |
| 17889 | 18037 | |
| 17890 | | if (target->value.type->id == ZigTypeIdComptimeInt) { |
| 17891 | | if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { |
| 17892 | | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpNumLitToConcrete, false); |
| 17893 | | } else { |
| 17894 | | return ira->codegen->invalid_instruction; |
| 17895 | | } |
| 17896 | | } |
| 17897 | | |
| 17898 | | if (target->value.type->id != ZigTypeIdInt) { |
| 18038 | if (target->value.type->id != ZigTypeIdInt && target->value.type->id != ZigTypeIdComptimeInt) { |
| 17899 | 18039 | ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", |
| 17900 | 18040 | buf_ptr(&target->value.type->name))); |
| 17901 | 18041 | return ira->codegen->invalid_instruction; |
| 17902 | 18042 | } |
| 17903 | 18043 | |
| 18044 | if (instr_is_comptime(target)) { |
| 18045 | return ir_implicit_cast(ira, target, dest_type); |
| 18046 | } |
| 18047 | |
| 18048 | if (dest_type->id == ZigTypeIdComptimeInt) { |
| 18049 | ir_add_error(ira, instruction->target, buf_sprintf("attempt to cast runtime value to '%s'", |
| 18050 | buf_ptr(&dest_type->name))); |
| 18051 | return ira->codegen->invalid_instruction; |
| 18052 | } |
| 18053 | |
| 17904 | 18054 | return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); |
| 17905 | 18055 | } |
| 17906 | 18056 | |