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