mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-18 20:02:22 -07: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);
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
|
||||
+13
-4
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user