authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-30 15:58:51-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-30 18:33:02-07:00
logc030ec1884ad7c553d6680944b47a1fc7653586f
tree5e11545a9a732ac2565b403bfd723c5f4f285998
parent67db2b85b771d8b0f9d765922951c31fce9c8cc2

LLVM: use unnamed struct llvm type for unions when necessary

The constant value lowering for unions was missing a check for whether the payload was itself an unnamed struct. Lowerings of other types already handle this case. closes #11971

1 files changed, 8 insertions(+), 6 deletions(-)

src/codegen/llvm.zig+8-6
......@@ -3401,6 +3401,13 @@ pub const DeclGen = struct {
34013401 const union_obj = tv.ty.cast(Type.Payload.Union).?.data;
34023402 const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, dg.module).?;
34033403 assert(union_obj.haveFieldTypes());
3404
3405 // Sometimes we must make an unnamed struct because LLVM does
3406 // not support bitcasting our payload struct to the true union payload type.
3407 // Instead we use an unnamed struct and every reference to the global
3408 // must pointer cast to the expected type before accessing the union.
3409 var need_unnamed: bool = layout.most_aligned_field != field_index;
3410
34043411 const field_ty = union_obj.fields.values()[field_index].ty;
34053412 const payload = p: {
34063413 if (!field_ty.hasRuntimeBitsIgnoreComptime()) {
......@@ -3408,6 +3415,7 @@ pub const DeclGen = struct {
34083415 break :p dg.context.intType(8).arrayType(padding_len).getUndef();
34093416 }
34103417 const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });
3418 need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field);
34113419 const field_size = field_ty.abiSize(target);
34123420 if (field_size == layout.payload_size) {
34133421 break :p field;
......@@ -3419,12 +3427,6 @@ pub const DeclGen = struct {
34193427 break :p dg.context.constStruct(&fields, fields.len, .True);
34203428 };
34213429
3422 // In this case we must make an unnamed struct because LLVM does
3423 // not support bitcasting our payload struct to the true union payload type.
3424 // Instead we use an unnamed struct and every reference to the global
3425 // must pointer cast to the expected type before accessing the union.
3426 const need_unnamed = layout.most_aligned_field != field_index;
3427
34283430 if (layout.tag_size == 0) {
34293431 const fields: [1]*const llvm.Value = .{payload};
34303432 if (need_unnamed) {