@@ -1671,6 +1671,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1671
1671
dst : RValue < ' gcc > ,
1672
1672
src : RValue < ' gcc > ,
1673
1673
order : AtomicOrdering ,
1674
+ ret_ptr : bool ,
1674
1675
) -> RValue < ' gcc > {
1675
1676
let size = get_maybe_pointer_size ( src) ;
1676
1677
let name = match op {
@@ -1698,14 +1699,18 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1698
1699
let atomic_function = self . context . get_builtin_function ( name) ;
1699
1700
let order = self . context . new_rvalue_from_int ( self . i32_type , order. to_gcc ( ) ) ;
1700
1701
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.
1701
1705
let void_ptr_type = self . context . new_type :: < * mut ( ) > ( ) ;
1702
1706
let volatile_void_ptr_type = void_ptr_type. make_volatile ( ) ;
1703
1707
let dst = self . context . new_cast ( self . location , dst, volatile_void_ptr_type) ;
1704
1708
// FIXME(antoyo): not sure why, but we have the wrong type here.
1705
1709
let new_src_type = atomic_function. get_param ( 1 ) . to_rvalue ( ) . get_type ( ) ;
1706
1710
let src = self . context . new_bitcast ( self . location , src, new_src_type) ;
1707
1711
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)
1709
1714
}
1710
1715
1711
1716
fn atomic_fence ( & mut self , order : AtomicOrdering , scope : SynchronizationScope ) {
0 commit comments