mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Fix bug with union literal checking crashing the compiler
This commit is contained in:
+4
-3
@@ -599,9 +599,10 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
|
|||||||
map_entity_set(&entity_map, hash_string(name), f);
|
map_entity_set(&entity_map, hash_string(name), f);
|
||||||
}
|
}
|
||||||
|
|
||||||
union_type->Record.fields = fields;
|
union_type->Record.fields = fields;
|
||||||
union_type->Record.field_count = field_count;
|
union_type->Record.fields_in_src_order = fields;
|
||||||
union_type->Record.are_offsets_set = false;
|
union_type->Record.field_count = field_count;
|
||||||
|
union_type->Record.are_offsets_set = false;
|
||||||
|
|
||||||
|
|
||||||
for_array(i, ut->variants) {
|
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);
|
Type *t = ir_type(slice_ptr);
|
||||||
GB_ASSERT(is_type_pointer(t));
|
GB_ASSERT(is_type_pointer(t));
|
||||||
t = type_deref(t);
|
t = type_deref(t);
|
||||||
GB_ASSERT(is_type_slice(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, 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, 1), len);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 2), capacity);
|
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"));
|
ir_emit_comment(proc, str_lit("union - child to parent"));
|
||||||
gbAllocator a = proc->module->allocator;
|
gbAllocator a = proc->module->allocator;
|
||||||
irValue *parent = ir_add_local_generated(proc, t);
|
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);
|
ir_emit_store(proc, underlying, value);
|
||||||
|
|
||||||
irValue *tag_ptr = ir_emit_union_tag_ptr(proc, parent);
|
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) {
|
if (elem->kind == AstNode_FieldValue) {
|
||||||
ast_node(fv, FieldValue, elem);
|
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];
|
index = sel.index.e[0];
|
||||||
elem = fv->value;
|
elem = fv->value;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+2
-2
@@ -170,8 +170,8 @@ Token make_token_ident(String s) {
|
|||||||
|
|
||||||
typedef struct ErrorCollector {
|
typedef struct ErrorCollector {
|
||||||
TokenPos prev;
|
TokenPos prev;
|
||||||
i64 count;
|
i64 count;
|
||||||
i64 warning_count;
|
i64 warning_count;
|
||||||
gbMutex mutex;
|
gbMutex mutex;
|
||||||
} ErrorCollector;
|
} ErrorCollector;
|
||||||
|
|
||||||
|
|||||||
+13
-4
@@ -1718,10 +1718,10 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
|||||||
if (t->Record.field_count > 0) {
|
if (t->Record.field_count > 0) {
|
||||||
Type *field_type = t->Record.fields[0]->type;
|
Type *field_type = t->Record.fields[0]->type;
|
||||||
type_path_push(path, field_type);
|
type_path_push(path, field_type);
|
||||||
|
i64 align = type_align_of_internal(allocator, field_type, path);
|
||||||
if (path->failure) {
|
if (path->failure) {
|
||||||
return FAILURE_ALIGNMENT;
|
return FAILURE_ALIGNMENT;
|
||||||
}
|
}
|
||||||
i64 align = type_align_of_internal(allocator, field_type, path);
|
|
||||||
type_path_pop(path);
|
type_path_pop(path);
|
||||||
if (max < align) {
|
if (max < align) {
|
||||||
max = align;
|
max = align;
|
||||||
@@ -1943,12 +1943,21 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
|
|||||||
if (path->failure) {
|
if (path->failure) {
|
||||||
return FAILURE_SIZE;
|
return FAILURE_SIZE;
|
||||||
}
|
}
|
||||||
// NOTE(bill): Zeroth field is invalid
|
|
||||||
type_set_offsets(allocator, t);
|
|
||||||
|
|
||||||
i64 max = 0;
|
i64 max = 0;
|
||||||
isize field_count = t->Record.field_count;
|
isize field_count = t->Record.field_count;
|
||||||
isize variant_count = t->Record.variant_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) {
|
if (field_count > 0) {
|
||||||
Type *end_type = t->Record.fields[field_count-1]->type;
|
Type *end_type = t->Record.fields[field_count-1]->type;
|
||||||
i64 end_offset = t->Record.offsets[field_count-1];
|
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) {
|
i64 type_offset_of(gbAllocator allocator, Type *t, i32 index) {
|
||||||
t = base_type(t);
|
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);
|
type_set_offsets(allocator, t);
|
||||||
if (gb_is_between(index, 0, t->Record.field_count-1)) {
|
if (gb_is_between(index, 0, t->Record.field_count-1)) {
|
||||||
return t->Record.offsets[index];
|
return t->Record.offsets[index];
|
||||||
|
|||||||
Reference in New Issue
Block a user