@@ -90,6 +90,8 @@ use rustc::hir;
9090use rustc:: ty:: layout:: { self , Layout } ;
9191use syntax:: ast;
9292
93+ use mir:: lvalue:: Alignment ;
94+
9395pub struct StatRecorder < ' a , ' tcx : ' a > {
9496 ccx : & ' a CrateContext < ' a , ' tcx > ,
9597 name : Option < String > ,
@@ -250,25 +252,25 @@ pub fn unsize_thin_ptr<'a, 'tcx>(
250252/// Coerce `src`, which is a reference to a value of type `src_ty`,
251253/// to a value of type `dst_ty` and store the result in `dst`
252254pub fn coerce_unsized_into < ' a , ' tcx > ( bcx : & Builder < ' a , ' tcx > ,
253- src : ValueRef ,
254- src_ty : Ty < ' tcx > ,
255- dst : ValueRef ,
256- dst_ty : Ty < ' tcx > ) {
255+ src : & LvalueRef < ' tcx > ,
256+ dst : & LvalueRef < ' tcx > ) {
257+ let src_ty = src . ty . to_ty ( bcx . tcx ( ) ) ;
258+ let dst_ty = dst . ty . to_ty ( bcx . tcx ( ) ) ;
257259 let coerce_ptr = || {
258260 let ( base, info) = if common:: type_is_fat_ptr ( bcx. ccx , src_ty) {
259261 // fat-ptr to fat-ptr unsize preserves the vtable
260262 // i.e. &'a fmt::Debug+Send => &'a fmt::Debug
261263 // So we need to pointercast the base to ensure
262264 // the types match up.
263- let ( base, info) = load_fat_ptr ( bcx, src, src_ty) ;
265+ let ( base, info) = load_fat_ptr ( bcx, src. llval , src . alignment , src_ty) ;
264266 let llcast_ty = type_of:: fat_ptr_base_ty ( bcx. ccx , dst_ty) ;
265267 let base = bcx. pointercast ( base, llcast_ty) ;
266268 ( base, info)
267269 } else {
268- let base = load_ty ( bcx, src, src_ty) ;
270+ let base = load_ty ( bcx, src. llval , src . alignment , src_ty) ;
269271 unsize_thin_ptr ( bcx, base, src_ty, dst_ty)
270272 } ;
271- store_fat_ptr ( bcx, base, info, dst, dst_ty) ;
273+ store_fat_ptr ( bcx, base, info, dst. llval , dst . alignment , dst_ty) ;
272274 } ;
273275 match ( & src_ty. sty , & dst_ty. sty ) {
274276 ( & ty:: TyRef ( ..) , & ty:: TyRef ( ..) ) |
@@ -290,21 +292,22 @@ pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
290292 monomorphize:: field_ty ( bcx. tcx ( ) , substs_b, f)
291293 } ) ;
292294
293- let src = LvalueRef :: new_sized_ty ( src, src_ty) ;
294- let dst = LvalueRef :: new_sized_ty ( dst, dst_ty) ;
295-
296295 let iter = src_fields. zip ( dst_fields) . enumerate ( ) ;
297296 for ( i, ( src_fty, dst_fty) ) in iter {
298297 if type_is_zero_size ( bcx. ccx , dst_fty) {
299298 continue ;
300299 }
301300
302- let src_f = src. trans_field_ptr ( bcx, i) ;
303- let dst_f = dst. trans_field_ptr ( bcx, i) ;
301+ let ( src_f, src_f_align ) = src. trans_field_ptr ( bcx, i) ;
302+ let ( dst_f, dst_f_align ) = dst. trans_field_ptr ( bcx, i) ;
304303 if src_fty == dst_fty {
305304 memcpy_ty ( bcx, dst_f, src_f, src_fty, None ) ;
306305 } else {
307- coerce_unsized_into ( bcx, src_f, src_fty, dst_f, dst_fty) ;
306+ coerce_unsized_into (
307+ bcx,
308+ & LvalueRef :: new_sized_ty ( src_f, src_fty, src_f_align) ,
309+ & LvalueRef :: new_sized_ty ( dst_f, dst_fty, dst_f_align)
310+ ) ;
308311 }
309312 }
310313 }
@@ -399,7 +402,8 @@ pub fn call_assume<'a, 'tcx>(b: &Builder<'a, 'tcx>, val: ValueRef) {
399402/// Helper for loading values from memory. Does the necessary conversion if the in-memory type
400403/// differs from the type used for SSA values. Also handles various special cases where the type
401404/// gives us better information about what we are loading.
402- pub fn load_ty < ' a , ' tcx > ( b : & Builder < ' a , ' tcx > , ptr : ValueRef , t : Ty < ' tcx > ) -> ValueRef {
405+ pub fn load_ty < ' a , ' tcx > ( b : & Builder < ' a , ' tcx > , ptr : ValueRef ,
406+ alignment : Alignment , t : Ty < ' tcx > ) -> ValueRef {
403407 let ccx = b. ccx ;
404408 if type_is_zero_size ( ccx, t) {
405409 return C_undef ( type_of:: type_of ( ccx, t) ) ;
@@ -419,54 +423,57 @@ pub fn load_ty<'a, 'tcx>(b: &Builder<'a, 'tcx>, ptr: ValueRef, t: Ty<'tcx>) -> V
419423 }
420424
421425 if t. is_bool ( ) {
422- b. trunc ( b. load_range_assert ( ptr, 0 , 2 , llvm:: False ) , Type :: i1 ( ccx) )
426+ b. trunc ( b. load_range_assert ( ptr, 0 , 2 , llvm:: False , alignment. to_align ( ) ) ,
427+ Type :: i1 ( ccx) )
423428 } else if t. is_char ( ) {
424429 // a char is a Unicode codepoint, and so takes values from 0
425430 // to 0x10FFFF inclusive only.
426- b. load_range_assert ( ptr, 0 , 0x10FFFF + 1 , llvm:: False )
431+ b. load_range_assert ( ptr, 0 , 0x10FFFF + 1 , llvm:: False , alignment . to_align ( ) )
427432 } else if ( t. is_region_ptr ( ) || t. is_box ( ) ) && !common:: type_is_fat_ptr ( ccx, t) {
428- b. load_nonnull ( ptr)
433+ b. load_nonnull ( ptr, alignment . to_align ( ) )
429434 } else {
430- b. load ( ptr)
435+ b. load ( ptr, alignment . to_align ( ) )
431436 }
432437}
433438
434439/// Helper for storing values in memory. Does the necessary conversion if the in-memory type
435440/// differs from the type used for SSA values.
436- pub fn store_ty < ' a , ' tcx > ( cx : & Builder < ' a , ' tcx > , v : ValueRef , dst : ValueRef , t : Ty < ' tcx > ) {
441+ pub fn store_ty < ' a , ' tcx > ( cx : & Builder < ' a , ' tcx > , v : ValueRef , dst : ValueRef ,
442+ dst_align : Alignment , t : Ty < ' tcx > ) {
437443 debug ! ( "store_ty: {:?} : {:?} <- {:?}" , Value ( dst) , t, Value ( v) ) ;
438444
439445 if common:: type_is_fat_ptr ( cx. ccx , t) {
440446 let lladdr = cx. extract_value ( v, abi:: FAT_PTR_ADDR ) ;
441447 let llextra = cx. extract_value ( v, abi:: FAT_PTR_EXTRA ) ;
442- store_fat_ptr ( cx, lladdr, llextra, dst, t) ;
448+ store_fat_ptr ( cx, lladdr, llextra, dst, dst_align , t) ;
443449 } else {
444- cx. store ( from_immediate ( cx, v) , dst, None ) ;
450+ cx. store ( from_immediate ( cx, v) , dst, dst_align . to_align ( ) ) ;
445451 }
446452}
447453
448454pub fn store_fat_ptr < ' a , ' tcx > ( cx : & Builder < ' a , ' tcx > ,
449455 data : ValueRef ,
450456 extra : ValueRef ,
451457 dst : ValueRef ,
458+ dst_align : Alignment ,
452459 _ty : Ty < ' tcx > ) {
453460 // FIXME: emit metadata
454- cx. store ( data, get_dataptr ( cx, dst) , None ) ;
455- cx. store ( extra, get_meta ( cx, dst) , None ) ;
461+ cx. store ( data, get_dataptr ( cx, dst) , dst_align . to_align ( ) ) ;
462+ cx. store ( extra, get_meta ( cx, dst) , dst_align . to_align ( ) ) ;
456463}
457464
458465pub fn load_fat_ptr < ' a , ' tcx > (
459- b : & Builder < ' a , ' tcx > , src : ValueRef , t : Ty < ' tcx >
466+ b : & Builder < ' a , ' tcx > , src : ValueRef , alignment : Alignment , t : Ty < ' tcx >
460467) -> ( ValueRef , ValueRef ) {
461468 let ptr = get_dataptr ( b, src) ;
462469 let ptr = if t. is_region_ptr ( ) || t. is_box ( ) {
463- b. load_nonnull ( ptr)
470+ b. load_nonnull ( ptr, alignment . to_align ( ) )
464471 } else {
465- b. load ( ptr)
472+ b. load ( ptr, alignment . to_align ( ) )
466473 } ;
467474
468475 // FIXME: emit metadata on `meta`.
469- let meta = b. load ( get_meta ( b, src) ) ;
476+ let meta = b. load ( get_meta ( b, src) , alignment . to_align ( ) ) ;
470477
471478 ( ptr, meta)
472479}
@@ -633,7 +640,7 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
633640 bcx. alloca ( fn_ty. ret . memory_ty ( ccx) , "sret_slot" )
634641 } ;
635642 // Can return unsized value
636- let mut dest_val = LvalueRef :: new_sized_ty ( dest, sig. output ( ) ) ;
643+ let mut dest_val = LvalueRef :: new_sized_ty ( dest, sig. output ( ) , Alignment :: AbiAligned ) ;
637644 dest_val. ty = LvalueTy :: Downcast {
638645 adt_def : sig. output ( ) . ty_adt_def ( ) . unwrap ( ) ,
639646 substs : substs,
@@ -642,7 +649,7 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
642649 let mut llarg_idx = fn_ty. ret . is_indirect ( ) as usize ;
643650 let mut arg_idx = 0 ;
644651 for ( i, arg_ty) in sig. inputs ( ) . iter ( ) . enumerate ( ) {
645- let lldestptr = dest_val. trans_field_ptr ( & bcx, i) ;
652+ let ( lldestptr, _ ) = dest_val. trans_field_ptr ( & bcx, i) ;
646653 let arg = & fn_ty. args [ arg_idx] ;
647654 arg_idx += 1 ;
648655 if common:: type_is_fat_ptr ( bcx. ccx , arg_ty) {
@@ -662,14 +669,12 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
662669 }
663670
664671 if let Some ( cast_ty) = fn_ty. ret . cast {
665- let load = bcx. load ( bcx. pointercast ( dest, cast_ty. ptr_to ( ) ) ) ;
666- let llalign = llalign_of_min ( ccx, fn_ty. ret . ty ) ;
667- unsafe {
668- llvm:: LLVMSetAlignment ( load, llalign) ;
669- }
670- bcx. ret ( load)
672+ bcx. ret ( bcx. load (
673+ bcx. pointercast ( dest, cast_ty. ptr_to ( ) ) ,
674+ Some ( llalign_of_min ( ccx, fn_ty. ret . ty ) )
675+ ) ) ;
671676 } else {
672- bcx. ret ( bcx. load ( dest) )
677+ bcx. ret ( bcx. load ( dest, None ) )
673678 }
674679 } else {
675680 bcx. ret_void ( ) ;
0 commit comments