@@ -143,7 +143,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
143143 // Simple cases, which don't need DST adjustment:
144144 // * no metadata available - just log the case
145145 // * known alignment - sized types, `[T]`, `str` or a foreign type
146- // * packed struct - there is no alignment padding
147146 match field. ty . kind ( ) {
148147 _ if self . llextra . is_none ( ) => {
149148 debug ! (
@@ -154,14 +153,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
154153 }
155154 _ if field. is_sized ( ) => return simple ( ) ,
156155 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- }
165156 _ => { }
166157 }
167158
@@ -186,7 +177,16 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
186177 let unaligned_offset = bx. cx ( ) . const_usize ( offset. bytes ( ) ) ;
187178
188179 // 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+ }
190190
191191 // Bump the unaligned offset up to the appropriate alignment
192192 let offset = round_up_const_value_to_alignment ( bx, unaligned_offset, unsized_align) ;
0 commit comments