Skip to content

Commit 784c48c

Browse files
committed
Redefine how union tag size is calculated to match alignment of the union
1 parent 008d8f2 commit 784c48c

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

src/ir.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7028,6 +7028,8 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) {
70287028
Type *fet = ir_type(field_expr);
70297029
// HACK TODO(bill): THIS IS A MASSIVE HACK!!!!
70307030
if (is_type_union(ft) && !are_types_identical(fet, ft) && !is_type_untyped(fet)) {
7031+
GB_ASSERT_MSG(union_variant_index(ft, fet) > 0, "%s", type_to_string(fet));
7032+
70317033
irValue *gep = ir_emit_struct_ep(proc, v, cast(i32)index);
70327034
ir_emit_store_union_variant(proc, gep, field_expr, fet);
70337035
} else {

src/types.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,11 +1632,26 @@ i64 union_tag_size(Type *u) {
16321632
return 0;
16331633
}
16341634

1635+
#if 1
1636+
// TODO(bill): Is this an okay approach?
1637+
i64 max_align = 1;
1638+
for_array(i, u->Union.variants) {
1639+
Type *variant_type = u->Union.variants[i];
1640+
i64 align = type_align_of(variant_type);
1641+
if (max_align < align) {
1642+
max_align = align;
1643+
}
1644+
}
1645+
1646+
u->Union.tag_size = gb_min(max_align, build_context.max_align);
1647+
return max_align;
1648+
#else
16351649
i64 bytes = next_pow2(cast(i64)(floor_log2(n)/8 + 1));
16361650
i64 tag_size = gb_max(bytes, 1);
16371651
16381652
u->Union.tag_size = tag_size;
16391653
return tag_size;
1654+
#endif
16401655
}
16411656

16421657
Type *union_tag_type(Type *u) {

0 commit comments

Comments
 (0)