| ... | ... | @@ -2327,16 +2327,21 @@ pub const Object = struct { |
| 2327 | 2327 | const layout = Type.getUnionLayout(union_type, zcu); |
| 2328 | 2328 | |
| 2329 | 2329 | if (layout.payload_size == 0) { |
| 2330 | | const tag_member = try o.builder.debugMemberType( |
| 2331 | | try o.builder.metadataString("tag"), |
| 2332 | | null, // file |
| 2333 | | ty_fwd_ref, |
| 2334 | | 0, // line |
| 2335 | | try o.getDebugType(pt, enum_tag_ty), |
| 2336 | | layout.tag_size * 8, |
| 2337 | | layout.tag_align.toByteUnits().? * 8, |
| 2338 | | 0, // offset |
| 2339 | | ); |
| 2330 | const fields_tuple: ?Builder.Metadata = fields: { |
| 2331 | if (layout.tag_size == 0) break :fields null; |
| 2332 | break :fields try o.builder.metadataTuple(&.{ |
| 2333 | try o.builder.debugMemberType( |
| 2334 | try o.builder.metadataString("tag"), |
| 2335 | null, // file |
| 2336 | ty_fwd_ref, |
| 2337 | 0, // line |
| 2338 | try o.getDebugType(pt, enum_tag_ty), |
| 2339 | layout.tag_size * 8, |
| 2340 | layout.tag_align.toByteUnits().? * 8, |
| 2341 | 0, // offset |
| 2342 | ), |
| 2343 | }); |
| 2344 | }; |
| 2340 | 2345 | return o.builder.debugStructType( |
| 2341 | 2346 | name, |
| 2342 | 2347 | file, |
| ... | ... | @@ -2345,7 +2350,7 @@ pub const Object = struct { |
| 2345 | 2350 | null, // underlying type |
| 2346 | 2351 | ty.abiSize(zcu) * 8, |
| 2347 | 2352 | ty.abiAlignment(zcu).toByteUnits().? * 8, |
| 2348 | | try o.builder.metadataTuple(&.{tag_member}), |
| 2353 | fields_tuple, |
| 2349 | 2354 | ); |
| 2350 | 2355 | } |
| 2351 | 2356 | |
| ... | ... | @@ -3141,12 +3146,16 @@ pub const Object = struct { |
| 3141 | 3146 | var struct_kind: Builder.Type.Structure.Kind = .normal; |
| 3142 | 3147 | // When we encounter a zero-bit field, we place it here so we know to map it to the next non-zero-bit field (if any). |
| 3143 | 3148 | var it = struct_type.iterateRuntimeOrder(ip); |
| 3149 | var max_field_ty_align: InternPool.Alignment = .@"1"; |
| 3144 | 3150 | while (it.next()) |field_index| { |
| 3145 | 3151 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 3152 | const field_ty_align = field_ty.abiAlignment(zcu); |
| 3153 | max_field_ty_align = max_field_ty_align.maxStrict(field_ty_align); |
| 3154 | |
| 3146 | 3155 | const prev_offset = offset; |
| 3147 | 3156 | offset = struct_type.field_offsets.get(ip)[field_index]; |
| 3148 | | if (@ctz(offset) < field_ty.abiAlignment(zcu).toLog2Units()) { |
| 3149 | | struct_kind = .@"packed"; |
| 3157 | if (@ctz(offset) < field_ty_align.toLog2Units()) { |
| 3158 | struct_kind = .@"packed"; // prevent unexpected padding before this field |
| 3150 | 3159 | } |
| 3151 | 3160 | |
| 3152 | 3161 | const padding_len = offset - prev_offset; |
| ... | ... | @@ -3184,6 +3193,9 @@ pub const Object = struct { |
| 3184 | 3193 | o.gpa, |
| 3185 | 3194 | try o.builder.arrayType(padding_len, .i8), |
| 3186 | 3195 | ); |
| 3196 | if (@ctz(offset) < max_field_ty_align.toLog2Units()) { |
| 3197 | struct_kind = .@"packed"; // prevent unexpected trailing padding |
| 3198 | } |
| 3187 | 3199 | } |
| 3188 | 3200 | |
| 3189 | 3201 | const ty = try o.builder.opaqueType(try o.builder.string(t.containerTypeName(ip).toSlice(ip))); |
| ... | ... | @@ -3883,7 +3895,7 @@ pub const Object = struct { |
| 3883 | 3895 | const payload = try o.lowerValue(pt, un.val); |
| 3884 | 3896 | const payload_ty = payload.typeOf(&o.builder); |
| 3885 | 3897 | if (payload_ty != union_ty.structFields(&o.builder)[ |
| 3886 | | @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)) |
| 3898 | @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) |
| 3887 | 3899 | ]) need_unnamed = true; |
| 3888 | 3900 | const field_size = field_ty.abiSize(zcu); |
| 3889 | 3901 | if (field_size == layout.payload_size) break :p payload; |
| ... | ... | @@ -6806,7 +6818,7 @@ pub const FuncGen = struct { |
| 6806 | 6818 | .@"union" => { |
| 6807 | 6819 | const union_llvm_ty = try o.lowerType(pt, struct_ty); |
| 6808 | 6820 | const layout = struct_ty.unionGetLayout(zcu); |
| 6809 | | const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)); |
| 6821 | const payload_index = @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)); |
| 6810 | 6822 | const field_ptr = |
| 6811 | 6823 | try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, ""); |
| 6812 | 6824 | const payload_alignment = layout.payload_align.toLlvm(); |
| ... | ... | @@ -11063,7 +11075,7 @@ pub const FuncGen = struct { |
| 11063 | 11075 | .@"union" => { |
| 11064 | 11076 | const layout = struct_ty.unionGetLayout(zcu); |
| 11065 | 11077 | if (layout.payload_size == 0 or struct_ty.containerLayout(zcu) == .@"packed") return struct_ptr; |
| 11066 | | const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align)); |
| 11078 | const payload_index = @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)); |
| 11067 | 11079 | const union_llvm_ty = try o.lowerType(pt, struct_ty); |
| 11068 | 11080 | return self.wip.gepStruct(union_llvm_ty, struct_ptr, payload_index, ""); |
| 11069 | 11081 | }, |