fix codegen for @intCast to u0

This commit is contained in:
Andrew Kelley 2018-09-17 20:32:51 -04:00
parent 15e59eb142
commit bfcfaaf5bd
No known key found for this signature in database
GPG Key ID: 4E7CD66038A4D47C
3 changed files with 36 additions and 0 deletions

View File

@ -1689,6 +1689,22 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, Z
if (actual_type->id == ZigTypeIdFloat) {
return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");
} else if (actual_type->id == ZigTypeIdInt) {
if (wanted_bits == 0) {
if (!want_runtime_safety)
return nullptr;
LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, expr_val, zero, "");
LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenOk");
LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenFail");
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
gen_safety_crash(g, PanicMsgIdCastTruncatedData);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
return nullptr;
}
LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
if (!want_runtime_safety) {
return trunc_val;

View File

@ -692,4 +692,11 @@ test "zero extend from u0 to u1" {
test "bit shift a u1" {
var x: u1 = 1;
var y = x << 0;
assert(y == 1);
}
test "@intCast to a u0" {
var x: u8 = 0;
var y: u0 = @intCast(u0, x);
assert(y == 0);
}

View File

@ -249,6 +249,19 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\}
);
cases.addRuntimeSafety("value does not fit in shortening cast - u0",
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
\\ const x = shorten_cast(1);
\\ if (x == 0) return error.Whatever;
\\}
\\fn shorten_cast(x: u8) u0 {
\\ return @intCast(u0, x);
\\}
);
cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer",
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);