Commit 258bc73eee

Andrew Kelley <superjoe30@gmail.com>
2016-01-03 04:13:10
fix implicit cast after unreachable bad code gen
1 parent 187d00c
Changed files (3)
src/codegen.cpp
@@ -203,21 +203,6 @@ static LLVMValueRef gen_array_ptr(CodeGen *g, AstNode *node) {
     AstNode *array_expr_node = node->data.array_access_expr.array_ref_expr;
 
     LLVMValueRef array_ptr = gen_expr(g, array_expr_node);
-    /*
-    if (array_expr_node->type == NodeTypeSymbol) {
-        VariableTableEntry *var = find_variable(array_expr_node->codegen_node->expr_node.block_context,
-                &array_expr_node->data.symbol);
-        assert(var);
-
-        array_ptr = var->value_ref;
-    } else if (array_expr_node->type == NodeTypeFieldAccessExpr) {
-        zig_panic("TODO gen array ptr field access expr");
-    } else if (array_expr_node->type == NodeTypeArrayAccessExpr) {
-        zig_panic("TODO gen array ptr array access expr");
-    } else {
-        array_ptr = gen_expr(g, array_expr_node);
-    }
-    */
 
     LLVMValueRef subscript_value = gen_expr(g, node->data.array_access_expr.subscript);
 
@@ -1363,6 +1348,9 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
 
     {
         TypeTableEntry *before_type = node->codegen_node->expr_node.type_entry;
+        if (before_type && before_type->id == TypeTableEntryIdUnreachable) {
+            return val;
+        }
         val = gen_cast_node(g, node, val, before_type, &node->codegen_node->expr_node.implicit_cast);
     }
 
std/std.zig
@@ -19,8 +19,8 @@ fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
         : "rcx", "r11")
 }
 
-pub fn getrandom(buf: &u8, count: usize, flags: u32) -> isize {
-    return syscall3(SYS_getrandom, buf as usize, count, flags as usize) as isize;
+pub fn getrandom(buf: &u8, count: usize, flags: u32) -> i32 {
+    return syscall3(SYS_getrandom, buf as usize, count, flags as usize) as i32;
 }
 
 pub fn write(fd: isize, buf: &const u8, count: usize) -> isize {
@@ -32,6 +32,30 @@ pub fn exit(status: i32) -> unreachable {
     unreachable;
 }
 
+// TODO error handling
+pub fn os_get_random_bytes(buf: &u8, count: usize) -> i32 {
+    return getrandom(buf, count, 0);
+}
+
+// TODO error handling
+// TODO handle buffering and flushing (mutex protected)
+pub fn print_str(str: string) -> isize { fprint_str(stdout_fileno, str) }
+
+// TODO error handling
+// TODO handle buffering and flushing (mutex protected)
+pub fn fprint_str(fd: isize, str: string) -> isize {
+    return write(fd, str.ptr, str.len);
+}
+
+// TODO handle buffering and flushing (mutex protected)
+// TODO error handling
+pub fn print_u64(x: u64) -> isize {
+    // TODO use max_u64_base10_digits instead of hardcoding 20
+    var buf: [u8; 20];
+    const len = buf_print_u64(buf.ptr, x);
+    return write(stdout_fileno, buf.ptr, len);
+}
+
 fn digit_to_char(digit: u64) -> u8 { '0' + (digit as u8) }
 
 const max_u64_base10_digits: usize = 20;
@@ -63,26 +87,3 @@ fn buf_print_u64(out_buf: &u8, x: u64) -> usize {
     return len;
 }
 
-// TODO error handling
-// TODO handle buffering and flushing (mutex protected)
-pub fn print_str(str: string) -> isize { fprint_str(stdout_fileno, str) }
-
-// TODO error handling
-// TODO handle buffering and flushing (mutex protected)
-pub fn fprint_str(fd: isize, str: string) -> isize {
-    return write(fd, str.ptr, str.len);
-}
-
-// TODO handle buffering and flushing (mutex protected)
-// TODO error handling
-pub fn print_u64(x: u64) -> isize {
-    // TODO use max_u64_base10_digits instead of hardcoding 20
-    var buf: [u8; 20];
-    const len = buf_print_u64(buf.ptr, x);
-    return write(stdout_fileno, buf.ptr, len);
-}
-
-// TODO error handling
-pub fn os_get_random_bytes(buf: &u8, count: usize) -> isize {
-    return getrandom(buf, count, 0);
-}
test/run_tests.cpp
@@ -682,6 +682,21 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
     return 0;
 }
     )SOURCE", "x is true\n");
+
+    add_simple_case("implicit cast after unreachable", R"SOURCE(
+use "std.zig";
+export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
+    const x = outer();
+    if (x == 1234) {
+        print_str("OK\n");
+    }
+    return 0;
+}
+fn inner() -> i32 { 1234 }
+fn outer() -> isize {
+    return inner();
+}
+    )SOURCE", "OK\n");
 }
 
 ////////////////////////////////////////////////////////////////////////////////////
@@ -978,6 +993,12 @@ fn f() {
     if (const x ?= true) { }
 }
     )SOURCE", 1, ".tmp_source.zig:3:20: error: expected maybe type");
+
+    add_compile_fail_case("cast unreachable", R"SOURCE(
+fn f() -> i32 {
+    (return 1) as i32
+}
+    )SOURCE", 1, ".tmp_source.zig:3:16: error: invalid cast from type 'unreachable' to 'i32'");
 }
 
 static void print_compiler_invocation(TestCase *test_case) {