aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-02-02 02:43:33 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-02-02 02:43:33 -0700
commit5ad84e47241cb412a0bfc6619eada1e4c7f4c1ec (patch)
treeabcb86cbf2cd339582e66bf6603164163af953a8 /src
parent6f1a7a0d70d53e7402380ce23a7b1e9c55aefa5c (diff)
downloadzig-5ad84e47241cb412a0bfc6619eada1e4c7f4c1ec.tar.gz
zig-5ad84e47241cb412a0bfc6619eada1e4c7f4c1ec.zip
unreachable causes a trap in debug mode
Diffstat (limited to 'src')
-rw-r--r--src/all_types.hpp1
-rw-r--r--src/codegen.cpp33
2 files changed, 32 insertions, 2 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 65456291e6..1f87ee128e 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1097,6 +1097,7 @@ struct CodeGen {
ImportTableEntry *bootstrap_import;
LLVMValueRef memcpy_fn_val;
LLVMValueRef memset_fn_val;
+ LLVMValueRef trap_fn_val;
bool error_during_imports;
uint32_t next_node_index;
uint32_t next_error_index;
diff --git a/src/codegen.cpp b/src/codegen.cpp
index b6cf0f2d96..63e1be54e5 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -991,9 +991,30 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
TypeTableEntry *expr_type = get_expr_type(expr_node);
assert(expr_type->id == TypeTableEntryIdErrorUnion);
TypeTableEntry *child_type = expr_type->data.error.child_type;
- // TODO in debug mode, put a panic here if the error is not 0
+
+ if (g->build_type != CodeGenBuildTypeRelease) {
+ LLVMValueRef err_val;
+ if (child_type->size_in_bits > 0) {
+ add_debug_source_node(g, node);
+ LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, "");
+ err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
+ } else {
+ err_val = expr_val;
+ }
+ LLVMValueRef zero = LLVMConstNull(g->err_tag_type->type_ref);
+ LLVMValueRef cond_val = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, zero, "");
+ LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrError");
+ LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrOk");
+ LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);
+
+ LLVMPositionBuilderAtEnd(g->builder, err_block);
+ LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
+ LLVMBuildUnreachable(g->builder);
+
+ LLVMPositionBuilderAtEnd(g->builder, ok_block);
+ }
+
if (child_type->size_in_bits > 0) {
- add_debug_source_node(g, node);
LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");
if (handle_is_ptr(child_type)) {
return child_val_ptr;
@@ -1898,6 +1919,9 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {
} else if (type_entry->id == TypeTableEntryIdUnreachable) {
assert(node->data.container_init_expr.entries.length == 0);
add_debug_source_node(g, node);
+ if (g->build_type != CodeGenBuildTypeRelease) {
+ LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
+ }
return LLVMBuildUnreachable(g->builder);
} else if (type_entry->id == TypeTableEntryIdVoid) {
assert(node->data.container_init_expr.entries.length == 0);
@@ -3085,6 +3109,11 @@ static BuiltinFnEntry *create_builtin_fn_with_arg_count(CodeGen *g, BuiltinFnId
static void define_builtin_fns(CodeGen *g) {
{
+ LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), nullptr, 0, false);
+ g->trap_fn_val = LLVMAddFunction(g->module, "llvm.debugtrap", fn_type);
+ assert(LLVMGetIntrinsicID(g->trap_fn_val));
+ }
+ {
BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy");
builtin_fn->return_type = g->builtin_types.entry_void;
builtin_fn->param_count = 3;