@@ -143,7 +143,8 @@ 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
146
+ // Note that looking at `field.align` is incorrect since that is not necessarily equal
147
+ // to the dynamic alignment of the type.
147
148
match field. ty . kind ( ) {
148
149
_ if self . llextra . is_none ( ) => {
149
150
debug ! (
@@ -154,14 +155,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
154
155
}
155
156
_ if field. is_sized ( ) => return simple ( ) ,
156
157
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
158
_ => { }
166
159
}
167
160
@@ -186,7 +179,16 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
186
179
let unaligned_offset = bx. cx ( ) . const_usize ( offset. bytes ( ) ) ;
187
180
188
181
// Get the alignment of the field
189
- let ( _, unsized_align) = glue:: size_and_align_of_dst ( bx, field. ty , meta) ;
182
+ let ( _, mut unsized_align) = glue:: size_and_align_of_dst ( bx, field. ty , meta) ;
183
+
184
+ // For packed types, we need to cap alignment.
185
+ if let ty:: Adt ( def, _) = self . layout . ty . kind ( )
186
+ && let Some ( packed) = def. repr ( ) . pack
187
+ {
188
+ let packed = bx. const_usize ( packed. bytes ( ) ) ;
189
+ let cmp = bx. icmp ( IntPredicate :: IntULT , unsized_align, packed) ;
190
+ unsized_align = bx. select ( cmp, unsized_align, packed)
191
+ }
190
192
191
193
// Bump the unaligned offset up to the appropriate alignment
192
194
let offset = round_up_const_value_to_alignment ( bx, unaligned_offset, unsized_align) ;
0 commit comments