authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-17 20:32:51-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-17 20:33:42-04:00
logbfcfaaf5bd5d2586d815ca5c10009975acf3e514
treec2a3580527c2fae812a9fc2c2af37679d7e4a33f
parent15e59eb142af9d4385b9ce5a277df27804e1794e
signaturelock-open Commit is signed but in an unrecognized format.

fix codegen for @intCast to u0


3 files changed, 36 insertions(+), 0 deletions(-)

src/codegen.cpp+16
......@@ -1689,6 +1689,22 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, Z
16891689 if (actual_type->id == ZigTypeIdFloat) {
16901690 return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");
16911691 } else if (actual_type->id == ZigTypeIdInt) {
1692 if (wanted_bits == 0) {
1693 if (!want_runtime_safety)
1694 return nullptr;
1695
1696 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
1697 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, expr_val, zero, "");
1698 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenOk");
1699 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenFail");
1700 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
1701
1702 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1703 gen_safety_crash(g, PanicMsgIdCastTruncatedData);
1704
1705 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1706 return nullptr;
1707 }
16921708 LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
16931709 if (!want_runtime_safety) {
16941710 return trunc_val;
test/cases/eval.zig+7
......@@ -692,4 +692,11 @@ test "zero extend from u0 to u1" {
692692test "bit shift a u1" {
693693 var x: u1 = 1;
694694 var y = x << 0;
695 assert(y == 1);
696}
697
698test "@intCast to a u0" {
699 var x: u8 = 0;
700 var y: u0 = @intCast(u0, x);
701 assert(y == 0);
695702}
test/runtime_safety.zig+13
......@@ -249,6 +249,19 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
249249 \\}
250250 );
251251
252 cases.addRuntimeSafety("value does not fit in shortening cast - u0",
253 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
254 \\ @import("std").os.exit(126);
255 \\}
256 \\pub fn main() !void {
257 \\ const x = shorten_cast(1);
258 \\ if (x == 0) return error.Whatever;
259 \\}
260 \\fn shorten_cast(x: u8) u0 {
261 \\ return @intCast(u0, x);
262 \\}
263 );
264
252265 cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer",
253266 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
254267 \\ @import("std").os.exit(126);