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