aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMitchell Hashimoto <mitchell.hashimoto@gmail.com>2022-03-25 09:53:07 -0700
committerMitchell Hashimoto <mitchell.hashimoto@gmail.com>2022-03-27 09:20:37 -0700
commit4ad98d07141cfba9ec9eb94c5daa13cc70c9d9cd (patch)
treec114871429dee37afe75a5427a6c1aa86517b592 /src
parent8fbac2e86d35bf363b67aba0f1915b7c9d32dcd0 (diff)
downloadzig-4ad98d07141cfba9ec9eb94c5daa13cc70c9d9cd.tar.gz
zig-4ad98d07141cfba9ec9eb94c5daa13cc70c9d9cd.zip
stage2: runtime safety check intCast to u0 must fit
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 473c9eab66..4a87145700 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -6782,6 +6782,20 @@ fn intCast(
}
if ((try sema.typeHasOnePossibleValue(block, dest_ty_src, dest_ty))) |opv| {
+ // requirement: intCast(u0, input) iff input == 0
+ if (runtime_safety and block.wantSafety()) {
+ try sema.requireRuntimeBlock(block, operand_src);
+ const target = sema.mod.getTarget();
+ const wanted_info = dest_ty.intInfo(target);
+ const wanted_bits = wanted_info.bits;
+
+ if (wanted_bits == 0) {
+ const zero_inst = try sema.addConstant(sema.typeOf(operand), Value.zero);
+ const is_in_range = try block.addBinOp(.cmp_eq, operand, zero_inst);
+ try sema.addSafetyCheck(block, is_in_range, .cast_truncated_data);
+ }
+ }
+
return sema.addConstant(dest_ty, opv);
}
@@ -6794,7 +6808,7 @@ fn intCast(
const actual_bits = actual_info.bits;
const wanted_bits = wanted_info.bits;
- // requirement: operand can fit into bit size of destination type
+ // requirement: bitSizeOf(operand) <= bitSizeOf(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);