| author | |
| committer | |
| log | dcca5cf1a9241e7274ae03a587b7e3313d673f3e |
| tree | 6b4ca8bd860d267f3c75ba37e78d0acd9bc49753 |
| parent | 289eab9177443bdfadfe750afda8f7f32f43be0f |
| parent | b8553b4813e971e50dcae7b8181e5f6771f3dbff |
| signature | Signed by PGP key 4AEE18F83AFDEB23 |
stage1: `@intcast` runtime safety for unsigned -> signed of same bit count5 files changed, 19 insertions(+), 7 deletions(-)
lib/std/special/compiler_rt/clzsi2_test.zig+1-1| ... | ... | @@ -4,7 +4,7 @@ const testing = @import("std").testing; |
| 4 | 4 | fn test__clzsi2(a: u32, expected: i32) void { |
| 5 | 5 | var nakedClzsi2 = clzsi2.__clzsi2; |
| 6 | 6 | var actualClzsi2 = @ptrCast(fn (a: i32) callconv(.C) i32, nakedClzsi2); |
| 7 | var x = @intCast(i32, a); | |
| 7 | var x = @bitCast(i32, a); | |
| 8 | 8 | var result = actualClzsi2(x); |
| 9 | 9 | testing.expectEqual(expected, result); |
| 10 | 10 | } |
lib/std/special/compiler_rt/int.zig+1-1| ... | ... | @@ -244,7 +244,7 @@ pub fn __udivsi3(n: u32, d: u32) callconv(.C) u32 { |
| 244 | 244 | // r.all -= d.all; |
| 245 | 245 | // carry = 1; |
| 246 | 246 | // } |
| 247 | const s = @intCast(i32, d -% r -% 1) >> @intCast(u5, n_uword_bits - 1); | |
| 247 | const s = @bitCast(i32, d -% r -% 1) >> @intCast(u5, n_uword_bits - 1); | |
| 248 | 248 | carry = @intCast(u32, s & 1); |
| 249 | 249 | r -= d & @bitCast(u32, s); |
| 250 | 250 | } |
lib/std/special/compiler_rt/udivmod.zig+1-1| ... | ... | @@ -184,7 +184,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 184 | 184 | // carry = 1; |
| 185 | 185 | // } |
| 186 | 186 | r_all = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421 |
| 187 | const s: SignedDoubleInt = @intCast(SignedDoubleInt, b -% r_all -% 1) >> (DoubleInt.bit_count - 1); | |
| 187 | const s: SignedDoubleInt = @bitCast(SignedDoubleInt, b -% r_all -% 1) >> (DoubleInt.bit_count - 1); | |
| 188 | 188 | carry = @intCast(u32, s & 1); |
| 189 | 189 | r_all -= b & @bitCast(DoubleInt, s); |
| 190 | 190 | r = @ptrCast(*[2]SingleInt, &r_all).*; // TODO issue #421 |
src/codegen.cpp+6-4| ... | ... | @@ -1535,9 +1535,11 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, Z |
| 1535 | 1535 | zig_unreachable(); |
| 1536 | 1536 | } |
| 1537 | 1537 | |
| 1538 | if (actual_type->id == ZigTypeIdInt && | |
| 1539 | !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed && | |
| 1540 | want_runtime_safety) | |
| 1538 | if (actual_type->id == ZigTypeIdInt && want_runtime_safety && ( | |
| 1539 | // negative to unsigned | |
| 1540 | (!wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed) || | |
| 1541 | // unsigned would become negative | |
| 1542 | (wanted_type->data.integral.is_signed && !actual_type->data.integral.is_signed && actual_bits == wanted_bits))) | |
| 1541 | 1543 | { |
| 1542 | 1544 | LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, actual_type)); |
| 1543 | 1545 | LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntSGE, expr_val, zero, ""); |
| ... | ... | @@ -1547,7 +1549,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, Z |
| 1547 | 1549 | LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); |
| 1548 | 1550 | |
| 1549 | 1551 | LLVMPositionBuilderAtEnd(g->builder, fail_block); |
| 1550 | gen_safety_crash(g, PanicMsgIdCastNegativeToUnsigned); | |
| 1552 | gen_safety_crash(g, actual_type->data.integral.is_signed ? PanicMsgIdCastNegativeToUnsigned : PanicMsgIdCastTruncatedData); | |
| 1551 | 1553 | |
| 1552 | 1554 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| 1553 | 1555 | } |
test/runtime_safety.zig+10| ... | ... | @@ -757,6 +757,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 757 | 757 | \\} |
| 758 | 758 | ); |
| 759 | 759 | |
| 760 | cases.addRuntimeSafety("unsigned integer not fitting in cast to signed integer - same bit count", | |
| 761 | \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { | |
| 762 | \\ @import("std").os.exit(126); | |
| 763 | \\} | |
| 764 | \\pub fn main() void { | |
| 765 | \\ var value: u8 = 245; | |
| 766 | \\ var casted = @intCast(i8, value); | |
| 767 | \\} | |
| 768 | ); | |
| 769 | ||
| 760 | 770 | cases.addRuntimeSafety("unwrap error", |
| 761 | 771 | \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { |
| 762 | 772 | \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) { |