| ... | ... | @@ -2933,8 +2933,8 @@ pub const Object = struct { |
| 2933 | 2933 | o.gpa, |
| 2934 | 2934 | try o.builder.arrayType(padding_len, .i8), |
| 2935 | 2935 | ); |
| 2936 | | if (@ctz(offset) < max_field_ty_align.toLog2Units()) { |
| 2937 | | struct_kind = .@"packed"; // prevent unexpected trailing padding |
| 2936 | if (struct_type.alignment.compareStrict(.lt, max_field_ty_align)) { |
| 2937 | struct_kind = .@"packed"; // prevent wrong alignment |
| 2938 | 2938 | } |
| 2939 | 2939 | } |
| 2940 | 2940 | |
| ... | ... | @@ -3013,14 +3013,22 @@ pub const Object = struct { |
| 3013 | 3013 | const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]); |
| 3014 | 3014 | const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty, repr); |
| 3015 | 3015 | |
| 3016 | | const payload_ty = ty: { |
| 3017 | | if (layout.most_aligned_field_size == layout.payload_size) { |
| 3018 | | break :ty aligned_field_llvm_ty; |
| 3016 | const struct_kind: Builder.Type.Structure.Kind = for (union_obj.field_types.get(ip)) |field_ty_ip| { |
| 3017 | const field_ty = Type.fromInterned(field_ty_ip); |
| 3018 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 3019 | if (layout.payload_align.compareStrict(.lt, field_ty.abiAlignment(zcu))) { |
| 3020 | break .@"packed"; // prevent wrong alignment |
| 3019 | 3021 | } |
| 3022 | } else .normal; |
| 3023 | |
| 3024 | const payload_ty = ty: { |
| 3020 | 3025 | const padding_len = if (layout.tag_size == 0) |
| 3021 | 3026 | layout.abi_size - layout.most_aligned_field_size |
| 3022 | 3027 | else |
| 3023 | 3028 | layout.payload_size - layout.most_aligned_field_size; |
| 3029 | if (padding_len == 0) { |
| 3030 | break :ty aligned_field_llvm_ty; |
| 3031 | } |
| 3024 | 3032 | break :ty try o.builder.structType(.@"packed", &.{ |
| 3025 | 3033 | aligned_field_llvm_ty, |
| 3026 | 3034 | try o.builder.arrayType(padding_len, .i8), |
| ... | ... | @@ -3033,7 +3041,7 @@ pub const Object = struct { |
| 3033 | 3041 | |
| 3034 | 3042 | o.builder.namedTypeSetBody( |
| 3035 | 3043 | ty, |
| 3036 | | try o.builder.structType(.normal, &.{payload_ty}), |
| 3044 | try o.builder.structType(struct_kind, &.{payload_ty}), |
| 3037 | 3045 | ); |
| 3038 | 3046 | return ty; |
| 3039 | 3047 | } |
| ... | ... | @@ -3061,7 +3069,7 @@ pub const Object = struct { |
| 3061 | 3069 | |
| 3062 | 3070 | o.builder.namedTypeSetBody( |
| 3063 | 3071 | ty, |
| 3064 | | try o.builder.structType(.normal, llvm_fields[0..llvm_fields_len]), |
| 3072 | try o.builder.structType(struct_kind, llvm_fields[0..llvm_fields_len]), |
| 3065 | 3073 | ); |
| 3066 | 3074 | return ty; |
| 3067 | 3075 | }, |
| ... | ... | @@ -3683,6 +3691,11 @@ pub const Object = struct { |
| 3683 | 3691 | const payload = if (un.tag != .none) p: { |
| 3684 | 3692 | const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; |
| 3685 | 3693 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 3694 | const field_size = field_ty.abiSize(zcu); |
| 3695 | const padding_len = if (layout.tag_size == 0) |
| 3696 | layout.abi_size - field_size |
| 3697 | else |
| 3698 | layout.payload_size - field_size; |
| 3686 | 3699 | |
| 3687 | 3700 | // Sometimes we must make an unnamed struct because LLVM does |
| 3688 | 3701 | // not support bitcasting our payload struct to the true union payload type. |
| ... | ... | @@ -3691,7 +3704,6 @@ pub const Object = struct { |
| 3691 | 3704 | need_unnamed = layout.most_aligned_field != field_index; |
| 3692 | 3705 | |
| 3693 | 3706 | if (!field_ty.hasRuntimeBits(zcu)) { |
| 3694 | | const padding_len = layout.payload_size; |
| 3695 | 3707 | break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8)); |
| 3696 | 3708 | } |
| 3697 | 3709 | const payload = try o.lowerValue(un.val, repr); |
| ... | ... | @@ -3699,9 +3711,7 @@ pub const Object = struct { |
| 3699 | 3711 | if (payload_ty != union_ty.structFields(&o.builder)[ |
| 3700 | 3712 | @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) |
| 3701 | 3713 | ]) need_unnamed = true; |
| 3702 | | const field_size = field_ty.abiSize(zcu); |
| 3703 | | if (field_size == layout.payload_size) break :p payload; |
| 3704 | | const padding_len = layout.payload_size - field_size; |
| 3714 | if (padding_len == 0) break :p payload; |
| 3705 | 3715 | const padding_ty = try o.builder.arrayType(padding_len, .i8); |
| 3706 | 3716 | break :p try o.builder.structConst( |
| 3707 | 3717 | try o.builder.structType(.@"packed", &.{ payload_ty, padding_ty }), |