@@ -1671,6 +1671,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
16711671 dst : RValue < ' gcc > ,
16721672 src : RValue < ' gcc > ,
16731673 order : AtomicOrdering ,
1674+ ret_ptr : bool ,
16741675 ) -> RValue < ' gcc > {
16751676 let size = get_maybe_pointer_size ( src) ;
16761677 let name = match op {
@@ -1698,14 +1699,18 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
16981699 let atomic_function = self . context . get_builtin_function ( name) ;
16991700 let order = self . context . new_rvalue_from_int ( self . i32_type , order. to_gcc ( ) ) ;
17001701
1702+ // FIXME: If `ret_ptr` is true and `src` is an integer, we should really tell GCC
1703+ // that this is a pointer operation that needs to preserve provenance -- but like LLVM,
1704+ // GCC does not currently seems to support that.
17011705 let void_ptr_type = self . context . new_type :: < * mut ( ) > ( ) ;
17021706 let volatile_void_ptr_type = void_ptr_type. make_volatile ( ) ;
17031707 let dst = self . context . new_cast ( self . location , dst, volatile_void_ptr_type) ;
17041708 // FIXME(antoyo): not sure why, but we have the wrong type here.
17051709 let new_src_type = atomic_function. get_param ( 1 ) . to_rvalue ( ) . get_type ( ) ;
17061710 let src = self . context . new_bitcast ( self . location , src, new_src_type) ;
17071711 let res = self . context . new_call ( self . location , atomic_function, & [ dst, src, order] ) ;
1708- self . context . new_cast ( self . location , res, src. get_type ( ) )
1712+ let res_type = if ret_ptr { void_ptr_type } else { src. get_type ( ) } ;
1713+ self . context . new_cast ( self . location , res, res_type)
17091714 }
17101715
17111716 fn atomic_fence ( & mut self , order : AtomicOrdering , scope : SynchronizationScope ) {
0 commit comments