diff options
| author | Mitchell Hashimoto <mitchell.hashimoto@gmail.com> | 2022-03-25 09:40:11 -0700 |
|---|---|---|
| committer | Mitchell Hashimoto <mitchell.hashimoto@gmail.com> | 2022-03-27 09:20:37 -0700 |
| commit | 8fbac2e86d35bf363b67aba0f1915b7c9d32dcd0 (patch) | |
| tree | 76a8a0dc223a24db92c680fc70262ab80ca9b702 /src | |
| parent | 01698528d1dff627b7e057651b137c20df7c7231 (diff) | |
| download | zig-8fbac2e86d35bf363b67aba0f1915b7c9d32dcd0.tar.gz zig-8fbac2e86d35bf363b67aba0f1915b7c9d32dcd0.zip | |
stage2: runtime safety check integer cast truncating bits
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 86e330a759..473c9eab66 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -6781,14 +6781,27 @@ fn intCast( return sema.fail(block, operand_src, "unable to cast runtime value to 'comptime_int'", .{}); } - // TODO insert safety check to make sure the value fits in the dest type - _ = runtime_safety; - if ((try sema.typeHasOnePossibleValue(block, dest_ty_src, dest_ty))) |opv| { return sema.addConstant(dest_ty, opv); } try sema.requireRuntimeBlock(block, operand_src); + if (runtime_safety) { + const target = sema.mod.getTarget(); + const operand_ty = sema.typeOf(operand); + const actual_info = operand_ty.intInfo(target); + const wanted_info = dest_ty.intInfo(target); + const actual_bits = actual_info.bits; + const wanted_bits = wanted_info.bits; + + // requirement: operand can fit into bit size of destination type + if (actual_bits > wanted_bits) { + const max_int = try dest_ty.maxInt(sema.arena, target); + const max_int_inst = try sema.addConstant(operand_ty, max_int); + const is_in_range = try block.addBinOp(.cmp_lte, operand, max_int_inst); + try sema.addSafetyCheck(block, is_in_range, .cast_truncated_data); + } + } return block.addTyOp(.intcast, dest_ty, operand); } @@ -16166,6 +16179,7 @@ pub const PanicId = enum { incorrect_alignment, invalid_error_code, index_out_of_bounds, + cast_truncated_data, }; fn addSafetyCheck( @@ -16288,6 +16302,7 @@ fn safetyPanic( .incorrect_alignment => "incorrect alignment", .invalid_error_code => "invalid error code", .index_out_of_bounds => "attempt to index out of bounds", + .cast_truncated_data => "integer cast truncated bits", }; const msg_inst = msg_inst: { |
