From 51f8c306d9fa32c849b26c2d95a45901a02f448e Mon Sep 17 00:00:00 2001 From: xackus <14938807+xackus@users.noreply.github.com> Date: Sun, 5 Jul 2020 17:58:21 +0200 Subject: [PATCH] stage1: add missing runtime safety for @intCast unsigned -> signed of same bit count --- src/codegen.cpp | 10 ++++++---- test/runtime_safety.zig | 10 ++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 18ef7d9182..2f72861bc2 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1535,9 +1535,11 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, Z zig_unreachable(); } - if (actual_type->id == ZigTypeIdInt && - !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed && - want_runtime_safety) + if (actual_type->id == ZigTypeIdInt && want_runtime_safety && ( + // negative to unsigned + (!wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed) || + // unsigned would become negative + (wanted_type->data.integral.is_signed && !actual_type->data.integral.is_signed && actual_bits == wanted_bits))) { LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, actual_type)); 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 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); LLVMPositionBuilderAtEnd(g->builder, fail_block); - gen_safety_crash(g, PanicMsgIdCastNegativeToUnsigned); + gen_safety_crash(g, actual_type->data.integral.is_signed ? PanicMsgIdCastNegativeToUnsigned : PanicMsgIdCastTruncatedData); LLVMPositionBuilderAtEnd(g->builder, ok_block); } diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig index e60d115a00..e27ae7e16e 100644 --- a/test/runtime_safety.zig +++ b/test/runtime_safety.zig @@ -757,6 +757,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\} ); + cases.addRuntimeSafety("unsigned integer not fitting in cast to signed integer - same bit count", + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { + \\ @import("std").os.exit(126); + \\} + \\pub fn main() void { + \\ var value: u8 = 245; + \\ var casted = @intCast(i8, value); + \\} + ); + cases.addRuntimeSafety("unwrap error", \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) {