@@ -143,7 +143,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
143
143
// Simple cases, which don't need DST adjustment:
144
144
// * no metadata available - just log the case
145
145
// * known alignment - sized types, `[T]`, `str` or a foreign type
146
- // * packed struct - there is no alignment padding
147
146
match field. ty . kind ( ) {
148
147
_ if self . llextra . is_none ( ) => {
149
148
debug ! (
@@ -154,14 +153,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
154
153
}
155
154
_ if field. is_sized ( ) => return simple ( ) ,
156
155
ty:: Slice ( ..) | ty:: Str | ty:: Foreign ( ..) => return simple ( ) ,
157
- ty:: Adt ( def, _) => {
158
- if def. repr ( ) . packed ( ) {
159
- // FIXME(eddyb) generalize the adjustment when we
160
- // start supporting packing to larger alignments.
161
- assert_eq ! ( self . layout. align. abi. bytes( ) , 1 ) ;
162
- return simple ( ) ;
163
- }
164
- }
165
156
_ => { }
166
157
}
167
158
@@ -186,7 +177,16 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
186
177
let unaligned_offset = bx. cx ( ) . const_usize ( offset. bytes ( ) ) ;
187
178
188
179
// Get the alignment of the field
189
- let ( _, unsized_align) = glue:: size_and_align_of_dst ( bx, field. ty , meta) ;
180
+ let ( _, mut unsized_align) = glue:: size_and_align_of_dst ( bx, field. ty , meta) ;
181
+
182
+ // For packed types, we need to cap alignment.
183
+ if let ty:: Adt ( def, _) = self . layout . ty . kind ( )
184
+ && let Some ( packed) = def. repr ( ) . pack
185
+ {
186
+ let packed = bx. const_usize ( packed. bytes ( ) ) ;
187
+ let cmp = bx. icmp ( IntPredicate :: IntULT , unsized_align, packed) ;
188
+ unsized_align = bx. select ( cmp, unsized_align, packed)
189
+ }
190
190
191
191
// Bump the unaligned offset up to the appropriate alignment
192
192
let offset = round_up_const_value_to_alignment ( bx, unaligned_offset, unsized_align) ;
0 commit comments