Fix type_union_tag_offset when all members are zero sized

This commit is contained in:
Jeroen van Rijn
2025-05-05 18:09:54 +02:00
parent c4719e75fd
commit 2224911aca
2 changed files with 6 additions and 5 deletions
+4 -3
View File
@@ -6032,12 +6032,13 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
// NOTE(jakubtomsu): forces calculation of variant_block_size // NOTE(jakubtomsu): forces calculation of variant_block_size
type_size_of(u); type_size_of(u);
i64 tag_offset = u->Union.variant_block_size; // NOTE(Jeroen): A tag offset of zero is perfectly fine if all members of the union are empty structs.
GB_ASSERT(tag_offset > 0); // What matters is that the tag size is > 0.
GB_ASSERT(u->Union.tag_size > 0);
operand->mode = Addressing_Constant; operand->mode = Addressing_Constant;
operand->type = t_untyped_integer; operand->type = t_untyped_integer;
operand->value = exact_value_i64(tag_offset); operand->value = exact_value_i64(u->Union.variant_block_size);
} }
break; break;
+2 -2
View File
@@ -4108,10 +4108,10 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) {
} }
i64 max = 0; i64 max = 0;
i64 field_size = 0;
for_array(i, t->Union.variants) { for_array(i, t->Union.variants) {
Type *variant_type = t->Union.variants[i]; Type *variant_type = t->Union.variants[i];
i64 size = type_size_of_internal(variant_type, path); i64 size = type_size_of_internal(variant_type, path);
if (max < size) { if (max < size) {
max = size; max = size;
@@ -4130,7 +4130,7 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) {
size = align_formula(max, tag_size); size = align_formula(max, tag_size);
// NOTE(bill): Calculate the padding between the common fields and the tag // NOTE(bill): Calculate the padding between the common fields and the tag
t->Union.tag_size = cast(i16)tag_size; t->Union.tag_size = cast(i16)tag_size;
t->Union.variant_block_size = size - field_size; t->Union.variant_block_size = size;
size += tag_size; size += tag_size;
} }