diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-04-18 21:20:41 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-04-18 21:20:41 +0100 |
| commit | 95692fda52320b6f6128d75f08ae5ac0e17c4857 (patch) | |
| tree | 988823875fcf386b7f41b0c25087cbbdf6c67a30 /src | |
| parent | 813a028ed0c8b3387436d959b4faa924117edab2 (diff) | |
Fix bug with union literal checking crashing the compiler
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_expr.c | 7 | ||||
| -rw-r--r-- | src/ir.c | 11 | ||||
| -rw-r--r-- | src/tokenizer.c | 4 | ||||
| -rw-r--r-- | src/types.c | 17 |
4 files changed, 25 insertions, 14 deletions
diff --git a/src/check_expr.c b/src/check_expr.c index a60193dae..c10eb7bd7 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -599,9 +599,10 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) { map_entity_set(&entity_map, hash_string(name), f); } - union_type->Record.fields = fields; - union_type->Record.field_count = field_count; - union_type->Record.are_offsets_set = false; + union_type->Record.fields = fields; + union_type->Record.fields_in_src_order = fields; + union_type->Record.field_count = field_count; + union_type->Record.are_offsets_set = false; for_array(i, ut->variants) { @@ -2525,14 +2525,14 @@ irValue *ir_string_len(irProcedure *proc, irValue *string) { } -void ir_fill_slice(irProcedure *proc, irValue *slice_ptr, irValue *data, irValue *count, irValue *capacity) { +void ir_fill_slice(irProcedure *proc, irValue *slice_ptr, irValue *data, irValue *len, irValue *cap) { Type *t = ir_type(slice_ptr); GB_ASSERT(is_type_pointer(t)); t = type_deref(t); GB_ASSERT(is_type_slice(t)); ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 0), data); - ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 1), count); - ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 2), capacity); + ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 1), len); + ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 2), cap); } @@ -2771,7 +2771,7 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { ir_emit_comment(proc, str_lit("union - child to parent")); gbAllocator a = proc->module->allocator; irValue *parent = ir_add_local_generated(proc, t); - irValue *underlying = ir_emit_conv(proc, parent, make_type_pointer(a, src_type)); + irValue *underlying = ir_emit_conv(proc, parent, make_type_pointer(a, f->type)); ir_emit_store(proc, underlying, value); irValue *tag_ptr = ir_emit_union_tag_ptr(proc, parent); @@ -5073,7 +5073,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { if (elem->kind == AstNode_FieldValue) { ast_node(fv, FieldValue, elem); - Selection sel = lookup_field(proc->module->allocator, bt, fv->field->Ident.string, false); + String name = fv->field->Ident.string; + Selection sel = lookup_field(proc->module->allocator, bt, name, false); index = sel.index.e[0]; elem = fv->value; } else { diff --git a/src/tokenizer.c b/src/tokenizer.c index 331ca0f77..469620450 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -170,8 +170,8 @@ Token make_token_ident(String s) { typedef struct ErrorCollector { TokenPos prev; - i64 count; - i64 warning_count; + i64 count; + i64 warning_count; gbMutex mutex; } ErrorCollector; diff --git a/src/types.c b/src/types.c index a806b13a2..8869505a9 100644 --- a/src/types.c +++ b/src/types.c @@ -1718,10 +1718,10 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) { if (t->Record.field_count > 0) { Type *field_type = t->Record.fields[0]->type; type_path_push(path, field_type); + i64 align = type_align_of_internal(allocator, field_type, path); if (path->failure) { return FAILURE_ALIGNMENT; } - i64 align = type_align_of_internal(allocator, field_type, path); type_path_pop(path); if (max < align) { max = align; @@ -1943,12 +1943,21 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) { if (path->failure) { return FAILURE_SIZE; } - // NOTE(bill): Zeroth field is invalid - type_set_offsets(allocator, t); i64 max = 0; isize field_count = t->Record.field_count; isize variant_count = t->Record.variant_count; + + // Check for recursive types + for (isize i = 0; i < field_count; i++) { + i64 size = type_size_of_internal(allocator, t->Record.fields[i]->type, path); + if (path->failure) { + return FAILURE_SIZE; + } + } + // NOTE(bill): Zeroth field is invalid + type_set_offsets(allocator, t); + if (field_count > 0) { Type *end_type = t->Record.fields[field_count-1]->type; i64 end_offset = t->Record.offsets[field_count-1]; @@ -1996,7 +2005,7 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) { i64 type_offset_of(gbAllocator allocator, Type *t, i32 index) { t = base_type(t); - if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) { + if (t->kind == Type_Record && (t->Record.kind == TypeRecord_Struct || t->Record.kind == TypeRecord_Union)) { type_set_offsets(allocator, t); if (gb_is_between(index, 0, t->Record.field_count-1)) { return t->Record.offsets[index]; |