@@ -652,18 +652,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
652652 unimplemented ! ( ) ;
653653 }
654654
655- fn load ( & mut self , _ty : Type < ' gcc > , ptr : RValue < ' gcc > , _align : Align ) -> RValue < ' gcc > {
656- // TODO(antoyo): use ty.
655+ fn load ( & mut self , pointee_ty : Type < ' gcc > , ptr : RValue < ' gcc > , _align : Align ) -> RValue < ' gcc > {
657656 let block = self . llbb ( ) ;
658657 let function = block. get_function ( ) ;
659658 // NOTE: instead of returning the dereference here, we have to assign it to a variable in
660659 // the current basic block. Otherwise, it could be used in another basic block, causing a
661660 // dereference after a drop, for instance.
662661 // TODO(antoyo): handle align of the load instruction.
662+ let ptr = self . context . new_cast ( None , ptr, pointee_ty. make_pointer ( ) ) ;
663663 let deref = ptr. dereference ( None ) . to_rvalue ( ) ;
664- let value_type = deref. get_type ( ) ;
665664 unsafe { RETURN_VALUE_COUNT += 1 } ;
666- let loaded_value = function. new_local ( None , value_type , & format ! ( "loadedValue{}" , unsafe { RETURN_VALUE_COUNT } ) ) ;
665+ let loaded_value = function. new_local ( None , pointee_ty , & format ! ( "loadedValue{}" , unsafe { RETURN_VALUE_COUNT } ) ) ;
667666 block. add_assignment ( None , loaded_value, deref) ;
668667 loaded_value. to_rvalue ( )
669668 }
@@ -715,7 +714,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
715714 OperandValue :: Ref ( place. llval , Some ( llextra) , place. align )
716715 }
717716 else if place. layout . is_gcc_immediate ( ) {
718- let load = self . load ( place. llval . get_type ( ) , place. llval , place. align ) ;
717+ let load = self . load (
718+ place. layout . gcc_type ( self , false ) ,
719+ place. llval ,
720+ place. align ,
721+ ) ;
719722 if let abi:: Abi :: Scalar ( ref scalar) = place. layout . abi {
720723 scalar_load_metadata ( self , load, scalar) ;
721724 }
@@ -727,7 +730,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
727730
728731 let mut load = |i, scalar : & abi:: Scalar , align| {
729732 let llptr = self . struct_gep ( pair_type, place. llval , i as u64 ) ;
730- let load = self . load ( llptr. get_type ( ) , llptr, align) ;
733+ let llty = place. layout . scalar_pair_element_gcc_type ( self , i, false ) ;
734+ let load = self . load ( llty, llptr, align) ;
731735 scalar_load_metadata ( self , load, scalar) ;
732736 if scalar. is_bool ( ) { self . trunc ( load, self . type_i1 ( ) ) } else { load }
733737 } ;
@@ -980,7 +984,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
980984 fn memmove ( & mut self , dst : RValue < ' gcc > , dst_align : Align , src : RValue < ' gcc > , src_align : Align , size : RValue < ' gcc > , flags : MemFlags ) {
981985 if flags. contains ( MemFlags :: NONTEMPORAL ) {
982986 // HACK(nox): This is inefficient but there is no nontemporal memmove.
983- let val = self . load ( src. get_type ( ) , src, src_align) ;
987+ let val = self . load ( src. get_type ( ) . get_pointee ( ) . expect ( "get_pointee" ) , src, src_align) ;
984988 let ptr = self . pointercast ( dst, self . type_ptr_to ( self . val_ty ( val) ) ) ;
985989 self . store_with_flags ( val, ptr, dst_align, flags) ;
986990 return ;
0 commit comments