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) {
153153 }
154154}
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
156184TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
157185 return get_int_type(g, false, bits_needed_for_unsigned(x));
158186}
......@@ -391,6 +419,7 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c
391419
392420 entry->type_ref = var_peer->type_ref;
393421 entry->di_type = var_peer->di_type;
422 entry->data.structure.complete = true;
394423
395424 *parent_pointer = entry;
396425 return entry;
......@@ -421,6 +450,8 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c
421450 buf_ptr(&entry->name), g->dummy_di_file, 0, entry->size_in_bits, entry->align_in_bits, 0,
422451 nullptr, di_element_types, element_count, 0, nullptr, "");
423452
453 entry->data.structure.complete = true;
454
424455 *parent_pointer = entry;
425456 return entry;
426457 }
......@@ -527,6 +558,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId fn_type_id) {
527558 gen_param_info->src_index = i;
528559 gen_param_info->gen_index = -1;
529560
561 assert(type_is_complete(type_entry));
530562 if (type_entry->size_in_bits > 0) {
531563 TypeTableEntry *gen_type;
532564 if (handle_is_ptr(type_entry)) {
......@@ -4751,7 +4783,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
47514783 if (!table_entry) {
47524784 table_entry = import->block_context->type_table.maybe_get(name);
47534785 }
4754 if (!table_entry) {
4786 if (!table_entry || !type_is_complete(table_entry->value)) {
47554787 decl_node->deps.put(name, node);
47564788 }
47574789 break;
src/codegen.cpp+1
......@@ -2830,6 +2830,7 @@ static void do_code_gen(CodeGen *g) {
28302830 arg_no = var->gen_arg_index + 1;
28312831
28322832 var->is_ptr = false;
2833 assert(var->gen_arg_index >= 0);
28332834 var->value_ref = LLVMGetParam(fn, var->gen_arg_index);
28342835 } else {
28352836 tag = LLVMZigTag_DW_auto_variable();
test/run_tests.cpp+36
......@@ -1513,6 +1513,42 @@ pub fn main(args: [][]u8) -> %void {
15131513 %%stdout.printf("OK\n");
15141514}
15151515 )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");
15161552}
15171553
15181554