@@ -402,8 +402,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
402402        indirect_dest :  PlaceRef < ' tcx ,  V > , 
403403    )  { 
404404        debug ! ( "OperandRef::store_unsized: operand={:?}, indirect_dest={:?}" ,  self ,  indirect_dest) ; 
405-         let  flags = MemFlags :: empty ( ) ; 
406- 
407405        // `indirect_dest` must have `*mut T` type. We extract `T` out of it. 
408406        let  unsized_ty = indirect_dest
409407            . layout 
@@ -416,17 +414,23 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
416414            bug ! ( "store_unsized called with a sized value" ) 
417415        } ; 
418416
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 ( ) ) ; 
427431
428432        // 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) ; 
430434        indirect_operand. store ( bx,  indirect_dest) ; 
431435    } 
432436} 
0 commit comments