authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-10 12:04:25-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-10 12:04:25-07:00
log0683bd8bf66c00d38f79d49319b5d80ac1f9a470
tree14a189d75708cbca15b770fdb8b947fd0f0a62c5
parentfddfc314d647b06fb65e8a94f670a537a1d4bbb4

fix crash when casting undefined to slice

also fix crash having to do with runtime allocated stack memory

3 files changed, 43 insertions(+), 31 deletions(-)

src/analyze.cpp+1
...@@ -3838,6 +3838,7 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex...@@ -3838,6 +3838,7 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex
3838 return;3838 return;
3839 }3839 }
3840 const_val->depends_on_compile_var = other_val->depends_on_compile_var;3840 const_val->depends_on_compile_var = other_val->depends_on_compile_var;
3841 const_val->undef = other_val->undef;
38413842
3842 assert(other_val != const_val);3843 assert(other_val != const_val);
3843 switch (node->data.fn_call_expr.cast_op) {3844 switch (node->data.fn_call_expr.cast_op) {
src/codegen.cpp+34-31
...@@ -2479,37 +2479,40 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa...@@ -2479,37 +2479,40 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
2479 value, variable->type, expr_type);2479 value, variable->type, expr_type);
2480 } else {2480 } else {
2481 bool ignore_uninit = false;2481 bool ignore_uninit = false;
2482 TypeTableEntry *var_type = get_type_for_type_node(var_decl->type);2482 // handle runtime stack allocation
2483 if (var_type->id == TypeTableEntryIdStruct &&2483 if (var_decl->type) {
2484 var_type->data.structure.is_unknown_size_array)2484 TypeTableEntry *var_type = get_type_for_type_node(var_decl->type);
2485 {2485 if (var_type->id == TypeTableEntryIdStruct &&
2486 assert(var_decl->type->type == NodeTypeArrayType);2486 var_type->data.structure.is_unknown_size_array)
2487 AstNode *size_node = var_decl->type->data.array_type.size;2487 {
2488 if (size_node) {2488 assert(var_decl->type->type == NodeTypeArrayType);
2489 ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val;2489 AstNode *size_node = var_decl->type->data.array_type.size;
2490 if (!const_val->ok) {2490 if (size_node) {
2491 TypeTableEntry *ptr_type = var_type->data.structure.fields[0].type_entry;2491 ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val;
2492 assert(ptr_type->id == TypeTableEntryIdPointer);2492 if (!const_val->ok) {
2493 TypeTableEntry *child_type = ptr_type->data.pointer.child_type;2493 TypeTableEntry *ptr_type = var_type->data.structure.fields[0].type_entry;
24942494 assert(ptr_type->id == TypeTableEntryIdPointer);
2495 LLVMValueRef size_val = gen_expr(g, size_node);2495 TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
24962496
2497 add_debug_source_node(g, source_node);2497 LLVMValueRef size_val = gen_expr(g, size_node);
2498 LLVMValueRef ptr_val = LLVMBuildArrayAlloca(g->builder, child_type->type_ref,2498
2499 size_val, "");2499 add_debug_source_node(g, source_node);
25002500 LLVMValueRef ptr_val = LLVMBuildArrayAlloca(g->builder, child_type->type_ref,
2501 // store the freshly allocated pointer in the unknown size array struct2501 size_val, "");
2502 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder,2502
2503 variable->value_ref, 0, "");2503 // store the freshly allocated pointer in the unknown size array struct
2504 LLVMBuildStore(g->builder, ptr_val, ptr_field_ptr);2504 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder,
25052505 variable->value_ref, 0, "");
2506 // store the size in the len field2506 LLVMBuildStore(g->builder, ptr_val, ptr_field_ptr);
2507 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder,2507
2508 variable->value_ref, 1, "");2508 // store the size in the len field
2509 LLVMBuildStore(g->builder, size_val, len_field_ptr);2509 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder,
25102510 variable->value_ref, 1, "");
2511 // don't clobber what we just did with debug initialization2511 LLVMBuildStore(g->builder, size_val, len_field_ptr);
2512 ignore_uninit = true;2512
2513 // don't clobber what we just did with debug initialization
2514 ignore_uninit = true;
2515 }
2513 }2516 }
2514 }2517 }
2515 }2518 }
test/self_hosted.zig+8
...@@ -609,3 +609,11 @@ entry:...@@ -609,3 +609,11 @@ entry:
609 if (b) goto exit;609 if (b) goto exit;
610}610}
611611
612
613#attribute("test")
614fn cast_undefined() {
615 const array: [100]u8 = undefined;
616 const slice = ([]u8)(array);
617 test_cast_undefined(slice);
618}
619fn test_cast_undefined(x: []u8) {}