@@ -1656,6 +1656,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
16561656 dst : RValue < ' gcc > ,
16571657 src : RValue < ' gcc > ,
16581658 order : AtomicOrdering ,
1659+ ret_ptr : bool ,
16591660 ) -> RValue < ' gcc > {
16601661 let size = get_maybe_pointer_size ( src) ;
16611662 let name = match op {
@@ -1683,14 +1684,18 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
16831684 let atomic_function = self . context . get_builtin_function ( name) ;
16841685 let order = self . context . new_rvalue_from_int ( self . i32_type , order. to_gcc ( ) ) ;
16851686
1687+ // FIXME: If `ret_ptr` is true and `src` is an integer, we should really tell GCC
1688+ // that this is a pointer operation that needs to preserve provenance -- but like LLVM,
1689+ // GCC does not currently seems to support that.
16861690 let void_ptr_type = self . context . new_type :: < * mut ( ) > ( ) ;
16871691 let volatile_void_ptr_type = void_ptr_type. make_volatile ( ) ;
16881692 let dst = self . context . new_cast ( self . location , dst, volatile_void_ptr_type) ;
16891693 // FIXME(antoyo): not sure why, but we have the wrong type here.
16901694 let new_src_type = atomic_function. get_param ( 1 ) . to_rvalue ( ) . get_type ( ) ;
16911695 let src = self . context . new_bitcast ( self . location , src, new_src_type) ;
16921696 let res = self . context . new_call ( self . location , atomic_function, & [ dst, src, order] ) ;
1693- self . context . new_cast ( self . location , res, src. get_type ( ) )
1697+ let res_type = if ret_ptr { void_ptr_type } else { src. get_type ( ) } ;
1698+ self . context . new_cast ( self . location , res, res_type)
16941699 }
16951700
16961701 fn atomic_fence ( & mut self , order : AtomicOrdering , scope : SynchronizationScope ) {
0 commit comments