| ... | @@ -6206,7 +6206,9 @@ static bool const_val_fits_in_num_lit(ConstExprValue *const_val, TypeTableEntry | ... | @@ -6206,7 +6206,9 @@ static bool const_val_fits_in_num_lit(ConstExprValue *const_val, TypeTableEntry |
| 6206 | (const_val->type->id == TypeTableEntryIdInt || const_val->type->id == TypeTableEntryIdNumLitInt))); | 6206 | (const_val->type->id == TypeTableEntryIdInt || const_val->type->id == TypeTableEntryIdNumLitInt))); |
| 6207 | } | 6207 | } |
| 6208 | | 6208 | |
| 6209 | static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type) { | 6209 | static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type, |
| | 6210 | bool explicit_cast) |
| | 6211 | { |
| 6210 | if (type_is_invalid(other_type)) { | 6212 | if (type_is_invalid(other_type)) { |
| 6211 | return false; | 6213 | return false; |
| 6212 | } | 6214 | } |
| ... | @@ -6243,6 +6245,32 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -6243,6 +6245,32 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 6243 | return true; | 6245 | return true; |
| 6244 | } | 6246 | } |
| 6245 | } | 6247 | } |
| | 6248 | if (explicit_cast && (other_type->id == TypeTableEntryIdInt || other_type->id == TypeTableEntryIdNumLitInt) && |
| | 6249 | const_val_is_float) |
| | 6250 | { |
| | 6251 | if (bigfloat_has_fraction(&const_val->data.x_bigfloat)) { |
| | 6252 | Buf *val_buf = buf_alloc(); |
| | 6253 | bigfloat_write_buf(val_buf, &const_val->data.x_bigfloat); |
| | 6254 | |
| | 6255 | ir_add_error(ira, instruction, |
| | 6256 | buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", |
| | 6257 | buf_ptr(val_buf), |
| | 6258 | buf_ptr(&other_type->name))); |
| | 6259 | return false; |
| | 6260 | } else { |
| | 6261 | BigInt bigint; |
| | 6262 | bigint_init_bigfloat(&bigint, &const_val->data.x_bigfloat); |
| | 6263 | if (other_type->id == TypeTableEntryIdNumLitInt) { |
| | 6264 | return true; |
| | 6265 | } else { |
| | 6266 | if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count, |
| | 6267 | other_type->data.integral.is_signed)) |
| | 6268 | { |
| | 6269 | return true; |
| | 6270 | } |
| | 6271 | } |
| | 6272 | } |
| | 6273 | } |
| 6246 | | 6274 | |
| 6247 | const char *num_lit_str; | 6275 | const char *num_lit_str; |
| 6248 | Buf *val_buf = buf_alloc(); | 6276 | Buf *val_buf = buf_alloc(); |
| ... | @@ -6425,12 +6453,12 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, | ... | @@ -6425,12 +6453,12 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 6425 | if (expected_type->id == TypeTableEntryIdPointer && | 6453 | if (expected_type->id == TypeTableEntryIdPointer && |
| 6426 | expected_type->data.pointer.is_const) | 6454 | expected_type->data.pointer.is_const) |
| 6427 | { | 6455 | { |
| 6428 | if (ir_num_lit_fits_in_other_type(ira, value, expected_type->data.pointer.child_type)) { | 6456 | if (ir_num_lit_fits_in_other_type(ira, value, expected_type->data.pointer.child_type, false)) { |
| 6429 | return ImplicitCastMatchResultYes; | 6457 | return ImplicitCastMatchResultYes; |
| 6430 | } else { | 6458 | } else { |
| 6431 | return ImplicitCastMatchResultReportedError; | 6459 | return ImplicitCastMatchResultReportedError; |
| 6432 | } | 6460 | } |
| 6433 | } else if (ir_num_lit_fits_in_other_type(ira, value, expected_type)) { | 6461 | } else if (ir_num_lit_fits_in_other_type(ira, value, expected_type, false)) { |
| 6434 | return ImplicitCastMatchResultYes; | 6462 | return ImplicitCastMatchResultYes; |
| 6435 | } else { | 6463 | } else { |
| 6436 | return ImplicitCastMatchResultReportedError; | 6464 | return ImplicitCastMatchResultReportedError; |
| ... | @@ -6542,7 +6570,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod | ... | @@ -6542,7 +6570,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 6542 | } else if (prev_type->id == TypeTableEntryIdNumLitInt || | 6570 | } else if (prev_type->id == TypeTableEntryIdNumLitInt || |
| 6543 | prev_type->id == TypeTableEntryIdNumLitFloat) | 6571 | prev_type->id == TypeTableEntryIdNumLitFloat) |
| 6544 | { | 6572 | { |
| 6545 | if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type)) { | 6573 | if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) { |
| 6546 | prev_inst = cur_inst; | 6574 | prev_inst = cur_inst; |
| 6547 | continue; | 6575 | continue; |
| 6548 | } else { | 6576 | } else { |
| ... | @@ -6551,7 +6579,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod | ... | @@ -6551,7 +6579,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 6551 | } else if (cur_type->id == TypeTableEntryIdNumLitInt || | 6579 | } else if (cur_type->id == TypeTableEntryIdNumLitInt || |
| 6552 | cur_type->id == TypeTableEntryIdNumLitFloat) | 6580 | cur_type->id == TypeTableEntryIdNumLitFloat) |
| 6553 | { | 6581 | { |
| 6554 | if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type)) { | 6582 | if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) { |
| 6555 | continue; | 6583 | continue; |
| 6556 | } else { | 6584 | } else { |
| 6557 | return ira->codegen->builtin_types.entry_invalid; | 6585 | return ira->codegen->builtin_types.entry_invalid; |
| ... | @@ -7636,7 +7664,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -7636,7 +7664,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 7636 | } else if (actual_type->id == TypeTableEntryIdNumLitInt || | 7664 | } else if (actual_type->id == TypeTableEntryIdNumLitInt || |
| 7637 | actual_type->id == TypeTableEntryIdNumLitFloat) | 7665 | actual_type->id == TypeTableEntryIdNumLitFloat) |
| 7638 | { | 7666 | { |
| 7639 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.maybe.child_type)) { | 7667 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.maybe.child_type, true)) { |
| 7640 | return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); | 7668 | return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); |
| 7641 | } else { | 7669 | } else { |
| 7642 | return ira->codegen->invalid_instruction; | 7670 | return ira->codegen->invalid_instruction; |
| ... | @@ -7658,7 +7686,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -7658,7 +7686,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 7658 | } else if (actual_type->id == TypeTableEntryIdNumLitInt || | 7686 | } else if (actual_type->id == TypeTableEntryIdNumLitInt || |
| 7659 | actual_type->id == TypeTableEntryIdNumLitFloat) | 7687 | actual_type->id == TypeTableEntryIdNumLitFloat) |
| 7660 | { | 7688 | { |
| 7661 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error.child_type)) { | 7689 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error.child_type, true)) { |
| 7662 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); | 7690 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| 7663 | } else { | 7691 | } else { |
| 7664 | return ira->codegen->invalid_instruction; | 7692 | return ira->codegen->invalid_instruction; |
| ... | @@ -7736,7 +7764,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -7736,7 +7764,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 7736 | return ira->codegen->invalid_instruction; | 7764 | return ira->codegen->invalid_instruction; |
| 7737 | | 7765 | |
| 7738 | return cast2; | 7766 | return cast2; |
| 7739 | } else if (ir_num_lit_fits_in_other_type(ira, value, wanted_type)) { | 7767 | } else if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { |
| 7740 | CastOp op; | 7768 | CastOp op; |
| 7741 | if ((actual_type->id == TypeTableEntryIdNumLitFloat && | 7769 | if ((actual_type->id == TypeTableEntryIdNumLitFloat && |
| 7742 | wanted_type->id == TypeTableEntryIdFloat) || | 7770 | wanted_type->id == TypeTableEntryIdFloat) || |
| ... | @@ -8630,7 +8658,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -8630,7 +8658,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 8630 | return ira->codegen->builtin_types.entry_invalid; | 8658 | return ira->codegen->builtin_types.entry_invalid; |
| 8631 | } | 8659 | } |
| 8632 | | 8660 | |
| 8633 | ir_num_lit_fits_in_other_type(ira, &bin_op_instruction->base, resolved_type); | 8661 | ir_num_lit_fits_in_other_type(ira, &bin_op_instruction->base, resolved_type, false); |
| 8634 | return resolved_type; | 8662 | return resolved_type; |
| 8635 | } | 8663 | } |
| 8636 | | 8664 | |