@@ -90,6 +90,8 @@ use rustc::hir;
90
90
use rustc:: ty:: layout:: { self , Layout } ;
91
91
use syntax:: ast;
92
92
93
+ use mir:: lvalue:: Alignment ;
94
+
93
95
pub struct StatRecorder < ' a , ' tcx : ' a > {
94
96
ccx : & ' a CrateContext < ' a , ' tcx > ,
95
97
name : Option < String > ,
@@ -250,25 +252,25 @@ pub fn unsize_thin_ptr<'a, 'tcx>(
250
252
/// Coerce `src`, which is a reference to a value of type `src_ty`,
251
253
/// to a value of type `dst_ty` and store the result in `dst`
252
254
pub 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 ( ) ) ;
257
259
let coerce_ptr = || {
258
260
let ( base, info) = if common:: type_is_fat_ptr ( bcx. ccx , src_ty) {
259
261
// fat-ptr to fat-ptr unsize preserves the vtable
260
262
// i.e. &'a fmt::Debug+Send => &'a fmt::Debug
261
263
// So we need to pointercast the base to ensure
262
264
// 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) ;
264
266
let llcast_ty = type_of:: fat_ptr_base_ty ( bcx. ccx , dst_ty) ;
265
267
let base = bcx. pointercast ( base, llcast_ty) ;
266
268
( base, info)
267
269
} else {
268
- let base = load_ty ( bcx, src, src_ty) ;
270
+ let base = load_ty ( bcx, src. llval , src . alignment , src_ty) ;
269
271
unsize_thin_ptr ( bcx, base, src_ty, dst_ty)
270
272
} ;
271
- store_fat_ptr ( bcx, base, info, dst, dst_ty) ;
273
+ store_fat_ptr ( bcx, base, info, dst. llval , dst . alignment , dst_ty) ;
272
274
} ;
273
275
match ( & src_ty. sty , & dst_ty. sty ) {
274
276
( & ty:: TyRef ( ..) , & ty:: TyRef ( ..) ) |
@@ -290,21 +292,22 @@ pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
290
292
monomorphize:: field_ty ( bcx. tcx ( ) , substs_b, f)
291
293
} ) ;
292
294
293
- let src = LvalueRef :: new_sized_ty ( src, src_ty) ;
294
- let dst = LvalueRef :: new_sized_ty ( dst, dst_ty) ;
295
-
296
295
let iter = src_fields. zip ( dst_fields) . enumerate ( ) ;
297
296
for ( i, ( src_fty, dst_fty) ) in iter {
298
297
if type_is_zero_size ( bcx. ccx , dst_fty) {
299
298
continue ;
300
299
}
301
300
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) ;
304
303
if src_fty == dst_fty {
305
304
memcpy_ty ( bcx, dst_f, src_f, src_fty, None ) ;
306
305
} 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
+ ) ;
308
311
}
309
312
}
310
313
}
@@ -399,7 +402,8 @@ pub fn call_assume<'a, 'tcx>(b: &Builder<'a, 'tcx>, val: ValueRef) {
399
402
/// Helper for loading values from memory. Does the necessary conversion if the in-memory type
400
403
/// differs from the type used for SSA values. Also handles various special cases where the type
401
404
/// 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 {
403
407
let ccx = b. ccx ;
404
408
if type_is_zero_size ( ccx, t) {
405
409
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
419
423
}
420
424
421
425
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) )
423
428
} else if t. is_char ( ) {
424
429
// a char is a Unicode codepoint, and so takes values from 0
425
430
// 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 ( ) )
427
432
} 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 ( ) )
429
434
} else {
430
- b. load ( ptr)
435
+ b. load ( ptr, alignment . to_align ( ) )
431
436
}
432
437
}
433
438
434
439
/// Helper for storing values in memory. Does the necessary conversion if the in-memory type
435
440
/// 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 > ) {
437
443
debug ! ( "store_ty: {:?} : {:?} <- {:?}" , Value ( dst) , t, Value ( v) ) ;
438
444
439
445
if common:: type_is_fat_ptr ( cx. ccx , t) {
440
446
let lladdr = cx. extract_value ( v, abi:: FAT_PTR_ADDR ) ;
441
447
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) ;
443
449
} else {
444
- cx. store ( from_immediate ( cx, v) , dst, None ) ;
450
+ cx. store ( from_immediate ( cx, v) , dst, dst_align . to_align ( ) ) ;
445
451
}
446
452
}
447
453
448
454
pub fn store_fat_ptr < ' a , ' tcx > ( cx : & Builder < ' a , ' tcx > ,
449
455
data : ValueRef ,
450
456
extra : ValueRef ,
451
457
dst : ValueRef ,
458
+ dst_align : Alignment ,
452
459
_ty : Ty < ' tcx > ) {
453
460
// 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 ( ) ) ;
456
463
}
457
464
458
465
pub 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 >
460
467
) -> ( ValueRef , ValueRef ) {
461
468
let ptr = get_dataptr ( b, src) ;
462
469
let ptr = if t. is_region_ptr ( ) || t. is_box ( ) {
463
- b. load_nonnull ( ptr)
470
+ b. load_nonnull ( ptr, alignment . to_align ( ) )
464
471
} else {
465
- b. load ( ptr)
472
+ b. load ( ptr, alignment . to_align ( ) )
466
473
} ;
467
474
468
475
// 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 ( ) ) ;
470
477
471
478
( ptr, meta)
472
479
}
@@ -633,7 +640,7 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
633
640
bcx. alloca ( fn_ty. ret . memory_ty ( ccx) , "sret_slot" )
634
641
} ;
635
642
// 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 ) ;
637
644
dest_val. ty = LvalueTy :: Downcast {
638
645
adt_def : sig. output ( ) . ty_adt_def ( ) . unwrap ( ) ,
639
646
substs : substs,
@@ -642,7 +649,7 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
642
649
let mut llarg_idx = fn_ty. ret . is_indirect ( ) as usize ;
643
650
let mut arg_idx = 0 ;
644
651
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) ;
646
653
let arg = & fn_ty. args [ arg_idx] ;
647
654
arg_idx += 1 ;
648
655
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>,
662
669
}
663
670
664
671
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
+ ) ) ;
671
676
} else {
672
- bcx. ret ( bcx. load ( dest) )
677
+ bcx. ret ( bcx. load ( dest, None ) )
673
678
}
674
679
} else {
675
680
bcx. ret_void ( ) ;
0 commit comments