aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-04-18 21:20:41 +0100
committerGinger Bill <bill@gingerbill.org>2017-04-18 21:20:41 +0100
commit95692fda52320b6f6128d75f08ae5ac0e17c4857 (patch)
tree988823875fcf386b7f41b0c25087cbbdf6c67a30 /src
parent813a028ed0c8b3387436d959b4faa924117edab2 (diff)
Fix bug with union literal checking crashing the compiler
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.c7
-rw-r--r--src/ir.c11
-rw-r--r--src/tokenizer.c4
-rw-r--r--src/types.c17
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) {
diff --git a/src/ir.c b/src/ir.c
index c49955b66..e0c277aec 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -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];