From 2224911aca77d15cfdb5ae19e16e9c88ed6edea9 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 5 May 2025 18:09:54 +0200 Subject: [PATCH] Fix `type_union_tag_offset` when all members are zero sized --- src/check_builtin.cpp | 7 ++++--- src/types.cpp | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 9d07de2b6..a315d1880 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -6032,12 +6032,13 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As // NOTE(jakubtomsu): forces calculation of variant_block_size type_size_of(u); - i64 tag_offset = u->Union.variant_block_size; - GB_ASSERT(tag_offset > 0); + // NOTE(Jeroen): A tag offset of zero is perfectly fine if all members of the union are empty structs. + // What matters is that the tag size is > 0. + GB_ASSERT(u->Union.tag_size > 0); operand->mode = Addressing_Constant; operand->type = t_untyped_integer; - operand->value = exact_value_i64(tag_offset); + operand->value = exact_value_i64(u->Union.variant_block_size); } break; diff --git a/src/types.cpp b/src/types.cpp index 9c9472a28..393e35ca1 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -4108,10 +4108,10 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) { } i64 max = 0; - i64 field_size = 0; for_array(i, t->Union.variants) { Type *variant_type = t->Union.variants[i]; + i64 size = type_size_of_internal(variant_type, path); if (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); // NOTE(bill): Calculate the padding between the common fields and the tag 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; }