@@ -402,8 +402,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
402
402
indirect_dest : PlaceRef < ' tcx , V > ,
403
403
) {
404
404
debug ! ( "OperandRef::store_unsized: operand={:?}, indirect_dest={:?}" , self , indirect_dest) ;
405
- let flags = MemFlags :: empty ( ) ;
406
-
407
405
// `indirect_dest` must have `*mut T` type. We extract `T` out of it.
408
406
let unsized_ty = indirect_dest
409
407
. layout
@@ -416,17 +414,23 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
416
414
bug ! ( "store_unsized called with a sized value" )
417
415
} ;
418
416
419
- // FIXME: choose an appropriate alignment, or use dynamic align somehow
420
- let max_align = Align :: from_bits ( 128 ) . unwrap ( ) ;
421
- let min_align = Align :: from_bits ( 8 ) . unwrap ( ) ;
422
-
423
- // Allocate an appropriate region on the stack, and copy the value into it
424
- let ( llsize, _) = glue:: size_and_align_of_dst ( bx, unsized_ty, Some ( llextra) ) ;
425
- let lldst = bx. byte_array_alloca ( llsize, max_align) ;
426
- bx. memcpy ( lldst, max_align, llptr, min_align, llsize, flags) ;
417
+ // Allocate an appropriate region on the stack, and copy the value into it. Since alloca
418
+ // doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the
419
+ // pointer manually.
420
+ let ( size, align) = glue:: size_and_align_of_dst ( bx, unsized_ty, Some ( llextra) ) ;
421
+ let one = bx. const_usize ( 1 ) ;
422
+ let align_minus_1 = bx. sub ( align, one) ;
423
+ let size_extra = bx. add ( size, align_minus_1) ;
424
+ let min_align = Align :: ONE ;
425
+ let alloca = bx. byte_array_alloca ( size_extra, min_align) ;
426
+ let address = bx. ptrtoint ( alloca, bx. type_isize ( ) ) ;
427
+ let neg_address = bx. neg ( address) ;
428
+ let offset = bx. and ( neg_address, align_minus_1) ;
429
+ let dst = bx. inbounds_gep ( bx. type_i8 ( ) , alloca, & [ offset] ) ;
430
+ bx. memcpy ( dst, min_align, llptr, min_align, size, MemFlags :: empty ( ) ) ;
427
431
428
432
// Store the allocated region and the extra to the indirect place.
429
- let indirect_operand = OperandValue :: Pair ( lldst , llextra) ;
433
+ let indirect_operand = OperandValue :: Pair ( dst , llextra) ;
430
434
indirect_operand. store ( bx, indirect_dest) ;
431
435
}
432
436
}
0 commit comments