| ... | ... | @@ -2898,8 +2898,8 @@ pub const Object = struct { |
| 2898 | 2898 | o.gpa, |
| 2899 | 2899 | try o.builder.arrayType(padding_len, .i8), |
| 2900 | 2900 | ); |
| 2901 | | if (@ctz(offset) < max_field_ty_align.toLog2Units()) { |
| 2902 | | struct_kind = .@"packed"; // prevent unexpected trailing padding |
| 2901 | if (struct_type.alignment.compareStrict(.lt, max_field_ty_align)) { |
| 2902 | struct_kind = .@"packed"; // prevent wrong alignment |
| 2903 | 2903 | } |
| 2904 | 2904 | } |
| 2905 | 2905 | |
| ... | ... | @@ -2978,14 +2978,22 @@ pub const Object = struct { |
| 2978 | 2978 | const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]); |
| 2979 | 2979 | const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty, repr); |
| 2980 | 2980 | |
| 2981 | | const payload_ty = ty: { |
| 2982 | | if (layout.most_aligned_field_size == layout.payload_size) { |
| 2983 | | break :ty aligned_field_llvm_ty; |
| 2981 | const struct_kind: Builder.Type.Structure.Kind = for (union_obj.field_types.get(ip)) |field_ty_ip| { |
| 2982 | const field_ty = Type.fromInterned(field_ty_ip); |
| 2983 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 2984 | if (layout.payload_align.compareStrict(.lt, field_ty.abiAlignment(zcu))) { |
| 2985 | break .@"packed"; // prevent wrong alignment |
| 2984 | 2986 | } |
| 2987 | } else .normal; |
| 2988 | |
| 2989 | const payload_ty = ty: { |
| 2985 | 2990 | const padding_len = if (layout.tag_size == 0) |
| 2986 | 2991 | layout.abi_size - layout.most_aligned_field_size |
| 2987 | 2992 | else |
| 2988 | 2993 | layout.payload_size - layout.most_aligned_field_size; |
| 2994 | if (padding_len == 0) { |
| 2995 | break :ty aligned_field_llvm_ty; |
| 2996 | } |
| 2989 | 2997 | break :ty try o.builder.structType(.@"packed", &.{ |
| 2990 | 2998 | aligned_field_llvm_ty, |
| 2991 | 2999 | try o.builder.arrayType(padding_len, .i8), |
| ... | ... | @@ -2998,7 +3006,7 @@ pub const Object = struct { |
| 2998 | 3006 | |
| 2999 | 3007 | o.builder.namedTypeSetBody( |
| 3000 | 3008 | ty, |
| 3001 | | try o.builder.structType(.normal, &.{payload_ty}), |
| 3009 | try o.builder.structType(struct_kind, &.{payload_ty}), |
| 3002 | 3010 | ); |
| 3003 | 3011 | return ty; |
| 3004 | 3012 | } |
| ... | ... | @@ -3026,7 +3034,7 @@ pub const Object = struct { |
| 3026 | 3034 | |
| 3027 | 3035 | o.builder.namedTypeSetBody( |
| 3028 | 3036 | ty, |
| 3029 | | try o.builder.structType(.normal, llvm_fields[0..llvm_fields_len]), |
| 3037 | try o.builder.structType(struct_kind, llvm_fields[0..llvm_fields_len]), |
| 3030 | 3038 | ); |
| 3031 | 3039 | return ty; |
| 3032 | 3040 | }, |
| ... | ... | @@ -3579,6 +3587,11 @@ pub const Object = struct { |
| 3579 | 3587 | const payload = if (un.tag != .none) p: { |
| 3580 | 3588 | const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; |
| 3581 | 3589 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 3590 | const field_size = field_ty.abiSize(zcu); |
| 3591 | const padding_len = if (layout.tag_size == 0) |
| 3592 | layout.abi_size - field_size |
| 3593 | else |
| 3594 | layout.payload_size - field_size; |
| 3582 | 3595 | |
| 3583 | 3596 | // Sometimes we must make an unnamed struct because LLVM does |
| 3584 | 3597 | // not support bitcasting our payload struct to the true union payload type. |
| ... | ... | @@ -3587,7 +3600,6 @@ pub const Object = struct { |
| 3587 | 3600 | need_unnamed = layout.most_aligned_field != field_index; |
| 3588 | 3601 | |
| 3589 | 3602 | if (!field_ty.hasRuntimeBits(zcu)) { |
| 3590 | | const padding_len = layout.payload_size; |
| 3591 | 3603 | break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8)); |
| 3592 | 3604 | } |
| 3593 | 3605 | const payload = try o.lowerValue(un.val, repr); |
| ... | ... | @@ -3595,9 +3607,7 @@ pub const Object = struct { |
| 3595 | 3607 | if (payload_ty != union_ty.structFields(&o.builder)[ |
| 3596 | 3608 | @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) |
| 3597 | 3609 | ]) need_unnamed = true; |
| 3598 | | const field_size = field_ty.abiSize(zcu); |
| 3599 | | if (field_size == layout.payload_size) break :p payload; |
| 3600 | | const padding_len = layout.payload_size - field_size; |
| 3610 | if (padding_len == 0) break :p payload; |
| 3601 | 3611 | const padding_ty = try o.builder.arrayType(padding_len, .i8); |
| 3602 | 3612 | break :p try o.builder.structConst( |
| 3603 | 3613 | try o.builder.structType(.@"packed", &.{ payload_ty, padding_ty }), |