authorgravatar for william@sengir.comWilliam Sengir <william@sengir.com> 2022-03-26 16:06:59-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-16 13:55:26-07:00
logafc714d5e5ff4d10a2b5dcc8f4c2eac8245de35c
tree37307dacf96435c72d7dd1508c360af48e26ff7f
parentc2980f332ed46e6ad7e8ac81b4dbef6d363447fb

stage2: implement runtime safety checks for shl_exact


1 files changed, 37 insertions(+), 2 deletions(-)

src/Sema.zig+37-2
...@@ -8826,8 +8826,6 @@ fn zirShl(...@@ -8826,8 +8826,6 @@ fn zirShl(
8826 return sema.addConstant(lhs_ty, val);8826 return sema.addConstant(lhs_ty, val);
8827 } else lhs_src;8827 } else lhs_src;
88288828
8829 // TODO: insert runtime safety check for shl_exact
8830
8831 const new_rhs = if (air_tag == .shl_sat) rhs: {8829 const new_rhs = if (air_tag == .shl_sat) rhs: {
8832 // Limit the RHS type for saturating shl to be an integer as small as the LHS.8830 // Limit the RHS type for saturating shl to be an integer as small as the LHS.
8833 if (rhs_is_comptime_int or8831 if (rhs_is_comptime_int or
...@@ -8845,6 +8843,41 @@ fn zirShl(...@@ -8845,6 +8843,41 @@ fn zirShl(
8845 } else rhs;8843 } else rhs;
88468844
8847 try sema.requireRuntimeBlock(block, runtime_src);8845 try sema.requireRuntimeBlock(block, runtime_src);
8846 if (block.wantSafety()) {
8847 const maybe_op_ov: ?Air.Inst.Tag = switch (air_tag) {
8848 .shl_exact => .shl_with_overflow,
8849 else => null,
8850 };
8851 if (maybe_op_ov) |op_ov_tag| {
8852 const op_ov_tuple_ty = try sema.overflowArithmeticTupleType(lhs_ty);
8853 const op_ov = try block.addInst(.{
8854 .tag = op_ov_tag,
8855 .data = .{ .ty_pl = .{
8856 .ty = try sema.addType(op_ov_tuple_ty),
8857 .payload = try sema.addExtra(Air.Bin{
8858 .lhs = lhs,
8859 .rhs = rhs,
8860 }),
8861 } },
8862 });
8863 const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty);
8864 const any_ov_bit = if (lhs_ty.zigTypeTag() == .Vector)
8865 try block.addInst(.{
8866 .tag = .reduce,
8867 .data = .{ .reduce = .{
8868 .operand = ov_bit,
8869 .operation = .Or,
8870 } },
8871 })
8872 else
8873 ov_bit;
8874 const zero_ov = try sema.addConstant(Type.@"u1", Value.zero);
8875 const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov);
8876
8877 try sema.addSafetyCheck(block, no_ov, .shl_overflow);
8878 return sema.tupleFieldValByIndex(block, src, op_ov, 0, op_ov_tuple_ty);
8879 }
8880 }
8848 return block.addBinOp(air_tag, lhs, new_rhs);8881 return block.addBinOp(air_tag, lhs, new_rhs);
8849}8882}
88508883
...@@ -16751,6 +16784,7 @@ pub const PanicId = enum {...@@ -16751,6 +16784,7 @@ pub const PanicId = enum {
16751 index_out_of_bounds,16784 index_out_of_bounds,
16752 cast_truncated_data,16785 cast_truncated_data,
16753 integer_overflow,16786 integer_overflow,
16787 shl_overflow,
16754};16788};
1675516789
16756fn addSafetyCheck(16790fn addSafetyCheck(
...@@ -16875,6 +16909,7 @@ fn safetyPanic(...@@ -16875,6 +16909,7 @@ fn safetyPanic(
16875 .index_out_of_bounds => "attempt to index out of bounds",16909 .index_out_of_bounds => "attempt to index out of bounds",
16876 .cast_truncated_data => "integer cast truncated bits",16910 .cast_truncated_data => "integer cast truncated bits",
16877 .integer_overflow => "integer overflow",16911 .integer_overflow => "integer overflow",
16912 .shl_overflow => "left shift overflowed bits",
16878 };16913 };
1687916914
16880 const msg_inst = msg_inst: {16915 const msg_inst = msg_inst: {