authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-02 19:09:53-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-02 19:09:53-07:00
log8058b5e0a92e4eac05ba19aabed1fc041353c69b
tree42b52618d9da5503dd4e7eb1702cf4d4be3a5a71
parent79adf55699a549841eba3eb07f1dbb19c4da9ed1

fix crash when incomplete struct used as argument

closes #107

3 files changed, 70 insertions(+), 1 deletions(-)

src/analyze.cpp+33-1
...@@ -153,6 +153,34 @@ static int bits_needed_for_unsigned(uint64_t x) {...@@ -153,6 +153,34 @@ static int bits_needed_for_unsigned(uint64_t x) {
153 }153 }
154}154}
155155
156static bool type_is_complete(TypeTableEntry *type_entry) {
157 switch (type_entry->id) {
158 case TypeTableEntryIdInvalid:
159 zig_unreachable();
160 case TypeTableEntryIdStruct:
161 return type_entry->data.structure.complete;
162 case TypeTableEntryIdEnum:
163 return type_entry->data.enumeration.complete;
164 case TypeTableEntryIdMetaType:
165 case TypeTableEntryIdVoid:
166 case TypeTableEntryIdBool:
167 case TypeTableEntryIdUnreachable:
168 case TypeTableEntryIdInt:
169 case TypeTableEntryIdFloat:
170 case TypeTableEntryIdPointer:
171 case TypeTableEntryIdArray:
172 case TypeTableEntryIdNumLitFloat:
173 case TypeTableEntryIdNumLitInt:
174 case TypeTableEntryIdUndefLit:
175 case TypeTableEntryIdMaybe:
176 case TypeTableEntryIdErrorUnion:
177 case TypeTableEntryIdPureError:
178 case TypeTableEntryIdFn:
179 case TypeTableEntryIdTypeDecl:
180 return true;
181 }
182}
183
156TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {184TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
157 return get_int_type(g, false, bits_needed_for_unsigned(x));185 return get_int_type(g, false, bits_needed_for_unsigned(x));
158}186}
...@@ -391,6 +419,7 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c...@@ -391,6 +419,7 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c
391419
392 entry->type_ref = var_peer->type_ref;420 entry->type_ref = var_peer->type_ref;
393 entry->di_type = var_peer->di_type;421 entry->di_type = var_peer->di_type;
422 entry->data.structure.complete = true;
394423
395 *parent_pointer = entry;424 *parent_pointer = entry;
396 return entry;425 return entry;
...@@ -421,6 +450,8 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c...@@ -421,6 +450,8 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c
421 buf_ptr(&entry->name), g->dummy_di_file, 0, entry->size_in_bits, entry->align_in_bits, 0,450 buf_ptr(&entry->name), g->dummy_di_file, 0, entry->size_in_bits, entry->align_in_bits, 0,
422 nullptr, di_element_types, element_count, 0, nullptr, "");451 nullptr, di_element_types, element_count, 0, nullptr, "");
423452
453 entry->data.structure.complete = true;
454
424 *parent_pointer = entry;455 *parent_pointer = entry;
425 return entry;456 return entry;
426 }457 }
...@@ -527,6 +558,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {...@@ -527,6 +558,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {
527 gen_param_info->src_index = i;558 gen_param_info->src_index = i;
528 gen_param_info->gen_index = -1;559 gen_param_info->gen_index = -1;
529560
561 assert(type_is_complete(type_entry));
530 if (type_entry->size_in_bits > 0) {562 if (type_entry->size_in_bits > 0) {
531 TypeTableEntry *gen_type;563 TypeTableEntry *gen_type;
532 if (handle_is_ptr(type_entry)) {564 if (handle_is_ptr(type_entry)) {
...@@ -4751,7 +4783,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode...@@ -4751,7 +4783,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
4751 if (!table_entry) {4783 if (!table_entry) {
4752 table_entry = import->block_context->type_table.maybe_get(name);4784 table_entry = import->block_context->type_table.maybe_get(name);
4753 }4785 }
4754 if (!table_entry) {4786 if (!table_entry || !type_is_complete(table_entry->value)) {
4755 decl_node->deps.put(name, node);4787 decl_node->deps.put(name, node);
4756 }4788 }
4757 break;4789 break;
src/codegen.cpp+1
...@@ -2830,6 +2830,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2830,6 +2830,7 @@ static void do_code_gen(CodeGen *g) {
2830 arg_no = var->gen_arg_index + 1;2830 arg_no = var->gen_arg_index + 1;
28312831
2832 var->is_ptr = false;2832 var->is_ptr = false;
2833 assert(var->gen_arg_index >= 0);
2833 var->value_ref = LLVMGetParam(fn, var->gen_arg_index);2834 var->value_ref = LLVMGetParam(fn, var->gen_arg_index);
2834 } else {2835 } else {
2835 tag = LLVMZigTag_DW_auto_variable();2836 tag = LLVMZigTag_DW_auto_variable();
test/run_tests.cpp+36
...@@ -1513,6 +1513,42 @@ pub fn main(args: [][]u8) -> %void {...@@ -1513,6 +1513,42 @@ pub fn main(args: [][]u8) -> %void {
1513 %%stdout.printf("OK\n");1513 %%stdout.printf("OK\n");
1514}1514}
1515 )SOURCE", "OK\n");1515 )SOURCE", "OK\n");
1516
1517
1518 add_simple_case("incomplete struct parameter top level decl", R"SOURCE(
1519import "std.zig";
1520struct A {
1521 b: B,
1522}
1523
1524struct B {
1525 c: C,
1526}
1527
1528struct C {
1529 x: i32,
1530
1531 fn d(c: C) {
1532 %%stdout.printf("OK\n");
1533 }
1534}
1535
1536fn foo(a: A) {
1537 a.b.c.d();
1538}
1539
1540pub fn main(args: [][]u8) -> %void {
1541 const a = A {
1542 .b = B {
1543 .c = C {
1544 .x = 13,
1545 },
1546 },
1547 };
1548 foo(a);
1549}
1550
1551 )SOURCE", "OK\n");
1516}1552}
15171553
15181554