| ... | @@ -6800,7 +6800,7 @@ fn intCast( | ... | @@ -6800,7 +6800,7 @@ fn intCast( |
| 6800 | } | 6800 | } |
| 6801 | | 6801 | |
| 6802 | try sema.requireRuntimeBlock(block, operand_src); | 6802 | try sema.requireRuntimeBlock(block, operand_src); |
| 6803 | if (runtime_safety) { | 6803 | if (runtime_safety and block.wantSafety()) { |
| 6804 | const target = sema.mod.getTarget(); | 6804 | const target = sema.mod.getTarget(); |
| 6805 | const operand_ty = sema.typeOf(operand); | 6805 | const operand_ty = sema.typeOf(operand); |
| 6806 | const actual_info = operand_ty.intInfo(target); | 6806 | const actual_info = operand_ty.intInfo(target); |
| ... | @@ -6808,8 +6808,21 @@ fn intCast( | ... | @@ -6808,8 +6808,21 @@ fn intCast( |
| 6808 | const actual_bits = actual_info.bits; | 6808 | const actual_bits = actual_info.bits; |
| 6809 | const wanted_bits = wanted_info.bits; | 6809 | const wanted_bits = wanted_info.bits; |
| 6810 | | 6810 | |
| 6811 | // requirement: bitSizeOf(operand) <= bitSizeOf(destination type) | 6811 | // requirement: signed to unsigned >= 0 |
| 6812 | if (actual_bits > wanted_bits) { | 6812 | if (actual_info.signedness == .signed and |
| | 6813 | wanted_info.signedness == .unsigned) |
| | 6814 | { |
| | 6815 | const zero_inst = try sema.addConstant(sema.typeOf(operand), Value.zero); |
| | 6816 | const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst); |
| | 6817 | try sema.addSafetyCheck(block, is_in_range, .cast_truncated_data); |
| | 6818 | } |
| | 6819 | |
| | 6820 | // requirement: unsigned int value fits into target type |
| | 6821 | if (actual_bits > wanted_bits or |
| | 6822 | (actual_bits == wanted_bits and |
| | 6823 | actual_info.signedness == .unsigned and |
| | 6824 | wanted_info.signedness == .signed)) |
| | 6825 | { |
| 6813 | const max_int = try dest_ty.maxInt(sema.arena, target); | 6826 | const max_int = try dest_ty.maxInt(sema.arena, target); |
| 6814 | const max_int_inst = try sema.addConstant(operand_ty, max_int); | 6827 | const max_int_inst = try sema.addConstant(operand_ty, max_int); |
| 6815 | const is_in_range = try block.addBinOp(.cmp_lte, operand, max_int_inst); | 6828 | const is_in_range = try block.addBinOp(.cmp_lte, operand, max_int_inst); |