authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-02 02:43:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-02 02:43:33-07:00
log5ad84e47241cb412a0bfc6619eada1e4c7f4c1ec
treeabcb86cbf2cd339582e66bf6603164163af953a8
parent6f1a7a0d70d53e7402380ce23a7b1e9c55aefa5c

unreachable causes a trap in debug mode


5 files changed, 38 insertions(+), 7 deletions(-)

doc/vim/syntax/zig.vim+1-1
...@@ -7,7 +7,7 @@ if exists("b:current_syntax")...@@ -7,7 +7,7 @@ if exists("b:current_syntax")
7 finish7 finish
8endif8endif
99
10syn keyword zigStorage const var extern volatile export pub noalias10syn keyword zigStorage const var extern volatile export pub noalias inline
11syn keyword zigStructure struct enum11syn keyword zigStructure struct enum
12syn keyword zigStatement goto break return continue asm defer12syn keyword zigStatement goto break return continue asm defer
13syn keyword zigConditional if else switch13syn keyword zigConditional if else switch
src/all_types.hpp+1
...@@ -1097,6 +1097,7 @@ struct CodeGen {...@@ -1097,6 +1097,7 @@ struct CodeGen {
1097 ImportTableEntry *bootstrap_import;1097 ImportTableEntry *bootstrap_import;
1098 LLVMValueRef memcpy_fn_val;1098 LLVMValueRef memcpy_fn_val;
1099 LLVMValueRef memset_fn_val;1099 LLVMValueRef memset_fn_val;
1100 LLVMValueRef trap_fn_val;
1100 bool error_during_imports;1101 bool error_during_imports;
1101 uint32_t next_node_index;1102 uint32_t next_node_index;
1102 uint32_t next_error_index;1103 uint32_t next_error_index;
src/codegen.cpp+31-2
...@@ -991,9 +991,30 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {...@@ -991,9 +991,30 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
991 TypeTableEntry *expr_type = get_expr_type(expr_node);991 TypeTableEntry *expr_type = get_expr_type(expr_node);
992 assert(expr_type->id == TypeTableEntryIdErrorUnion);992 assert(expr_type->id == TypeTableEntryIdErrorUnion);
993 TypeTableEntry *child_type = expr_type->data.error.child_type;993 TypeTableEntry *child_type = expr_type->data.error.child_type;
994 // TODO in debug mode, put a panic here if the error is not 0994
995 if (g->build_type != CodeGenBuildTypeRelease) {
996 LLVMValueRef err_val;
997 if (child_type->size_in_bits > 0) {
998 add_debug_source_node(g, node);
999 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, "");
1000 err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
1001 } else {
1002 err_val = expr_val;
1003 }
1004 LLVMValueRef zero = LLVMConstNull(g->err_tag_type->type_ref);
1005 LLVMValueRef cond_val = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, zero, "");
1006 LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrError");
1007 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrOk");
1008 LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);
1009
1010 LLVMPositionBuilderAtEnd(g->builder, err_block);
1011 LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
1012 LLVMBuildUnreachable(g->builder);
1013
1014 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1015 }
1016
995 if (child_type->size_in_bits > 0) {1017 if (child_type->size_in_bits > 0) {
996 add_debug_source_node(g, node);
997 LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");1018 LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");
998 if (handle_is_ptr(child_type)) {1019 if (handle_is_ptr(child_type)) {
999 return child_val_ptr;1020 return child_val_ptr;
...@@ -1898,6 +1919,9 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {...@@ -1898,6 +1919,9 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {
1898 } else if (type_entry->id == TypeTableEntryIdUnreachable) {1919 } else if (type_entry->id == TypeTableEntryIdUnreachable) {
1899 assert(node->data.container_init_expr.entries.length == 0);1920 assert(node->data.container_init_expr.entries.length == 0);
1900 add_debug_source_node(g, node);1921 add_debug_source_node(g, node);
1922 if (g->build_type != CodeGenBuildTypeRelease) {
1923 LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
1924 }
1901 return LLVMBuildUnreachable(g->builder);1925 return LLVMBuildUnreachable(g->builder);
1902 } else if (type_entry->id == TypeTableEntryIdVoid) {1926 } else if (type_entry->id == TypeTableEntryIdVoid) {
1903 assert(node->data.container_init_expr.entries.length == 0);1927 assert(node->data.container_init_expr.entries.length == 0);
...@@ -3084,6 +3108,11 @@ static BuiltinFnEntry *create_builtin_fn_with_arg_count(CodeGen *g, BuiltinFnId...@@ -3084,6 +3108,11 @@ static BuiltinFnEntry *create_builtin_fn_with_arg_count(CodeGen *g, BuiltinFnId
3084}3108}
30853109
3086static void define_builtin_fns(CodeGen *g) {3110static void define_builtin_fns(CodeGen *g) {
3111 {
3112 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), nullptr, 0, false);
3113 g->trap_fn_val = LLVMAddFunction(g->module, "llvm.debugtrap", fn_type);
3114 assert(LLVMGetIntrinsicID(g->trap_fn_val));
3115 }
3087 {3116 {
3088 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy");3117 BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy");
3089 builtin_fn->return_type = g->builtin_types.entry_void;3118 builtin_fn->return_type = g->builtin_types.entry_void;
std/math.zig+5
...@@ -27,3 +27,8 @@ pub fn f64_is_nan(f: f64) -> bool {...@@ -27,3 +27,8 @@ pub fn f64_is_nan(f: f64) -> bool {
27pub fn f64_is_inf(f: f64) -> bool {27pub fn f64_is_inf(f: f64) -> bool {
28 f == f64_get_neg_inf() || f == f64_get_pos_inf()28 f == f64_get_neg_inf() || f == f64_get_pos_inf()
29}29}
30
31pub fn min_isize(x: isize, y: isize) -> isize {
32 if (x < y) x else y
33}
34
std/std.zig-4
...@@ -372,7 +372,3 @@ pub fn buf_print_f64(out_buf: []u8, x: f64, decimals: isize) -> isize {...@@ -372,7 +372,3 @@ pub fn buf_print_f64(out_buf: []u8, x: f64, decimals: isize) -> isize {
372372
373 len373 len
374}374}
375
376fn min_isize(x: isize, y: isize) -> isize {
377 if (x < y) x else y
378}