authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-02 12:37:19-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-02 12:37:19-07:00
log5824b15249c8fb42aba5ca347d7dc702a4a00a9f
tree3143991da761ae6ed1680af8bfd6ec6a139a9dba
parent5ad84e47241cb412a0bfc6619eada1e4c7f4c1ec

codegen: ?? prefix operator causes trap in debug mode


1 files changed, 43 insertions(+), 2 deletions(-)

src/codegen.cpp+43-2
......@@ -1028,8 +1028,49 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
10281028 case PrefixOpUnwrapMaybe:
10291029 {
10301030 LLVMValueRef expr_val = gen_expr(g, expr_node);
1031 // TODO in debug mode, put a panic here if null
1032 return gen_unwrap_maybe(g, expr_node, expr_val);
1031
1032 TypeTableEntry *expr_type = get_expr_type(expr_node);
1033 assert(expr_type->id == TypeTableEntryIdMaybe);
1034 TypeTableEntry *child_type = expr_type->data.maybe.child_type;
1035
1036 if (g->build_type != CodeGenBuildTypeRelease) {
1037 add_debug_source_node(g, node);
1038 LLVMValueRef cond_val;
1039 if (child_type->id == TypeTableEntryIdPointer ||
1040 child_type->id == TypeTableEntryIdFn)
1041 {
1042 cond_val = LLVMBuildICmp(g->builder, LLVMIntNE, expr_val,
1043 LLVMConstNull(child_type->type_ref), "");
1044 } else {
1045 LLVMValueRef maybe_null_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");
1046 cond_val = LLVMBuildLoad(g->builder, maybe_null_ptr, "");
1047 }
1048
1049 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapMaybeOk");
1050 LLVMBasicBlockRef null_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapMaybeNull");
1051 LLVMBuildCondBr(g->builder, cond_val, ok_block, null_block);
1052
1053 LLVMPositionBuilderAtEnd(g->builder, null_block);
1054 LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
1055 LLVMBuildUnreachable(g->builder);
1056
1057 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1058 }
1059
1060
1061 if (child_type->id == TypeTableEntryIdPointer ||
1062 child_type->id == TypeTableEntryIdFn)
1063 {
1064 return expr_val;
1065 } else {
1066 add_debug_source_node(g, node);
1067 LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, "");
1068 if (handle_is_ptr(child_type)) {
1069 return maybe_field_ptr;
1070 } else {
1071 return LLVMBuildLoad(g->builder, maybe_field_ptr, "");
1072 }
1073 }
10331074 }
10341075 }
10351076 zig_unreachable();