authorgravatar for mitchell.hashimoto@gmail.comMitchell Hashimoto <mitchell.hashimoto@gmail.com> 2022-03-25 16:45:29-07:00
committergravatar for mitchell.hashimoto@gmail.comMitchell Hashimoto <mitchell.hashimoto@gmail.com> 2022-03-27 09:20:37-07:00
log3c918184385f9ffc80693fb2683b4a9b574f9b66
tree8f2b18b9d3757ffee5c2540a8793218daf1b02f8
parent4ad98d07141cfba9ec9eb94c5daa13cc70c9d9cd
signature Commit is signed but in an unrecognized format.

stage2: runtime safety check intCast signedness


1 files changed, 16 insertions(+), 3 deletions(-)

src/Sema.zig+16-3
......@@ -6800,7 +6800,7 @@ fn intCast(
68006800 }
68016801
68026802 try sema.requireRuntimeBlock(block, operand_src);
6803 if (runtime_safety) {
6803 if (runtime_safety and block.wantSafety()) {
68046804 const target = sema.mod.getTarget();
68056805 const operand_ty = sema.typeOf(operand);
68066806 const actual_info = operand_ty.intInfo(target);
......@@ -6808,8 +6808,21 @@ fn intCast(
68086808 const actual_bits = actual_info.bits;
68096809 const wanted_bits = wanted_info.bits;
68106810
6811 // requirement: bitSizeOf(operand) <= bitSizeOf(destination type)
6812 if (actual_bits > wanted_bits) {
6811 // requirement: signed to unsigned >= 0
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 {
68136826 const max_int = try dest_ty.maxInt(sema.arena, target);
68146827 const max_int_inst = try sema.addConstant(operand_ty, max_int);
68156828 const is_in_range = try block.addBinOp(.cmp_lte, operand, max_int_inst);