diff options
| author | William Sengir <william@sengir.com> | 2022-03-26 16:06:59 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-05-16 13:55:26 -0700 |
| commit | afc714d5e5ff4d10a2b5dcc8f4c2eac8245de35c (patch) | |
| tree | 37307dacf96435c72d7dd1508c360af48e26ff7f /src | |
| parent | c2980f332ed46e6ad7e8ac81b4dbef6d363447fb (diff) | |
| download | zig-afc714d5e5ff4d10a2b5dcc8f4c2eac8245de35c.tar.gz zig-afc714d5e5ff4d10a2b5dcc8f4c2eac8245de35c.zip | |
stage2: implement runtime safety checks for shl_exact
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index a37fc2ef50..471639ba96 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -8826,8 +8826,6 @@ fn zirShl( return sema.addConstant(lhs_ty, val); } else lhs_src; - // TODO: insert runtime safety check for shl_exact - const new_rhs = if (air_tag == .shl_sat) rhs: { // Limit the RHS type for saturating shl to be an integer as small as the LHS. if (rhs_is_comptime_int or @@ -8845,6 +8843,41 @@ fn zirShl( } else rhs; try sema.requireRuntimeBlock(block, runtime_src); + if (block.wantSafety()) { + const maybe_op_ov: ?Air.Inst.Tag = switch (air_tag) { + .shl_exact => .shl_with_overflow, + else => null, + }; + if (maybe_op_ov) |op_ov_tag| { + const op_ov_tuple_ty = try sema.overflowArithmeticTupleType(lhs_ty); + const op_ov = try block.addInst(.{ + .tag = op_ov_tag, + .data = .{ .ty_pl = .{ + .ty = try sema.addType(op_ov_tuple_ty), + .payload = try sema.addExtra(Air.Bin{ + .lhs = lhs, + .rhs = rhs, + }), + } }, + }); + const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty); + const any_ov_bit = if (lhs_ty.zigTypeTag() == .Vector) + try block.addInst(.{ + .tag = .reduce, + .data = .{ .reduce = .{ + .operand = ov_bit, + .operation = .Or, + } }, + }) + else + ov_bit; + const zero_ov = try sema.addConstant(Type.@"u1", Value.zero); + const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); + + try sema.addSafetyCheck(block, no_ov, .shl_overflow); + return sema.tupleFieldValByIndex(block, src, op_ov, 0, op_ov_tuple_ty); + } + } return block.addBinOp(air_tag, lhs, new_rhs); } @@ -16751,6 +16784,7 @@ pub const PanicId = enum { index_out_of_bounds, cast_truncated_data, integer_overflow, + shl_overflow, }; fn addSafetyCheck( @@ -16875,6 +16909,7 @@ fn safetyPanic( .index_out_of_bounds => "attempt to index out of bounds", .cast_truncated_data => "integer cast truncated bits", .integer_overflow => "integer overflow", + .shl_overflow => "left shift overflowed bits", }; const msg_inst = msg_inst: { |
