| author | |
| committer | |
| log | 76d099950aa2e5fee4897c8bc401946f39ed87a4 |
| tree | ce8b2a2ed2673777f2f4a0aa73351c47491bfd0c |
| parent | 0782586b15302654501ebbcab3a2c63755a6fadb |
4 files changed, 18 insertions(+), 12 deletions(-)
src/Sema.zig+5-2| ... | ... | @@ -8092,6 +8092,7 @@ fn intCast( |
| 8092 | 8092 | const is_in_range = try block.addBinOp(.cmp_lte, diff_unsigned, dest_range); |
| 8093 | 8093 | break :ok is_in_range; |
| 8094 | 8094 | }; |
| 8095 | // TODO negative_to_unsigned? | |
| 8095 | 8096 | try sema.addSafetyCheck(block, ok, .cast_truncated_data); |
| 8096 | 8097 | } else { |
| 8097 | 8098 | const ok = if (is_vector) ok: { |
| ... | ... | @@ -8116,7 +8117,7 @@ fn intCast( |
| 8116 | 8117 | const ok = if (is_vector) ok: { |
| 8117 | 8118 | const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero); |
| 8118 | 8119 | const zero_inst = try sema.addConstant(operand_ty, zero_val); |
| 8119 | const is_in_range = try block.addCmpVector(operand, zero_inst, .lte, try sema.addType(operand_ty)); | |
| 8120 | const is_in_range = try block.addCmpVector(operand, zero_inst, .gte, try sema.addType(operand_ty)); | |
| 8120 | 8121 | const all_in_range = try block.addInst(.{ |
| 8121 | 8122 | .tag = .reduce, |
| 8122 | 8123 | .data = .{ .reduce = .{ |
| ... | ... | @@ -8130,7 +8131,7 @@ fn intCast( |
| 8130 | 8131 | const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst); |
| 8131 | 8132 | break :ok is_in_range; |
| 8132 | 8133 | }; |
| 8133 | try sema.addSafetyCheck(block, ok, .cast_truncated_data); | |
| 8134 | try sema.addSafetyCheck(block, ok, .negative_to_unsigned); | |
| 8134 | 8135 | } |
| 8135 | 8136 | } |
| 8136 | 8137 | return block.addTyOp(.intcast, dest_ty, operand); |
| ... | ... | @@ -18849,6 +18850,7 @@ pub const PanicId = enum { |
| 18849 | 18850 | incorrect_alignment, |
| 18850 | 18851 | invalid_error_code, |
| 18851 | 18852 | cast_truncated_data, |
| 18853 | negative_to_unsigned, | |
| 18852 | 18854 | integer_overflow, |
| 18853 | 18855 | shl_overflow, |
| 18854 | 18856 | shr_overflow, |
| ... | ... | @@ -19069,6 +19071,7 @@ fn safetyPanic( |
| 19069 | 19071 | .incorrect_alignment => "incorrect alignment", |
| 19070 | 19072 | .invalid_error_code => "invalid error code", |
| 19071 | 19073 | .cast_truncated_data => "integer cast truncated bits", |
| 19074 | .negative_to_unsigned => "attempt to cast negative value to unsigned integer", | |
| 19072 | 19075 | .integer_overflow => "integer overflow", |
| 19073 | 19076 | .shl_overflow => "left shift overflowed bits", |
| 19074 | 19077 | .shr_overflow => "right shift overflowed bits", |
test/cases/safety/signed integer not fitting in cast to unsigned integer - widening.zig	+6-4| ... | ... | @@ -1,9 +1,11 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | |
| 3 | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { |
| 4 | _ = message; | |
| 5 | 4 | _ = stack_trace; |
| 6 | std.process.exit(0); | |
| 5 | if (std.mem.eql(u8, message, "attempt to cast negative value to unsigned integer")) { | |
| 6 | std.process.exit(0); | |
| 7 | } | |
| 8 | std.process.exit(1); | |
| 7 | 9 | } |
| 8 | 10 | pub fn main() !void { |
| 9 | 11 | var value: c_short = -1; |
| ... | ... | @@ -12,5 +14,5 @@ pub fn main() !void { |
| 12 | 14 | return error.TestFailed; |
| 13 | 15 | } |
| 14 | 16 | // run |
| 15 | // backend=stage1 | |
| 16 | // target=native | |
| \ No newline at end of file | ||
| 17 | // backend=llvm | |
| 18 | // target=native |
test/cases/safety/signed integer not fitting in cast to unsigned integer.zig	+6-5| ... | ... | @@ -1,11 +1,12 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | |
| 3 | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { |
| 4 | _ = message; | |
| 5 | 4 | _ = stack_trace; |
| 6 | std.process.exit(0); | |
| 5 | if (std.mem.eql(u8, message, "attempt to cast negative value to unsigned integer")) { | |
| 6 | std.process.exit(0); | |
| 7 | } | |
| 8 | std.process.exit(1); | |
| 7 | 9 | } |
| 8 | ||
| 9 | 10 | pub fn main() !void { |
| 10 | 11 | const x = unsigned_cast(-10); |
| 11 | 12 | if (x == 0) return error.Whatever; |
| ... | ... | @@ -15,5 +16,5 @@ fn unsigned_cast(x: i32) u32 { |
| 15 | 16 | return @intCast(u32, x); |
| 16 | 17 | } |
| 17 | 18 | // run |
| 18 | // backend=stage1 | |
| 19 | // target=native | |
| \ No newline at end of file | ||
| 19 | // backend=llvm | |
| 20 | // target=native |
test/cases/safety/signed-unsigned vector cast.zig	+1-1| ... | ... | @@ -16,5 +16,5 @@ pub fn main() !void { |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | 18 | // run |
| 19 | // backend=stage1 | |
| 19 | // backend=llvm | |
| 20 | 20 | // target=native |