@@ -1656,6 +1656,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1656
1656
dst : RValue < ' gcc > ,
1657
1657
src : RValue < ' gcc > ,
1658
1658
order : AtomicOrdering ,
1659
+ ret_ptr : bool ,
1659
1660
) -> RValue < ' gcc > {
1660
1661
let size = get_maybe_pointer_size ( src) ;
1661
1662
let name = match op {
@@ -1683,14 +1684,18 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1683
1684
let atomic_function = self . context . get_builtin_function ( name) ;
1684
1685
let order = self . context . new_rvalue_from_int ( self . i32_type , order. to_gcc ( ) ) ;
1685
1686
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.
1686
1690
let void_ptr_type = self . context . new_type :: < * mut ( ) > ( ) ;
1687
1691
let volatile_void_ptr_type = void_ptr_type. make_volatile ( ) ;
1688
1692
let dst = self . context . new_cast ( self . location , dst, volatile_void_ptr_type) ;
1689
1693
// FIXME(antoyo): not sure why, but we have the wrong type here.
1690
1694
let new_src_type = atomic_function. get_param ( 1 ) . to_rvalue ( ) . get_type ( ) ;
1691
1695
let src = self . context . new_bitcast ( self . location , src, new_src_type) ;
1692
1696
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)
1694
1699
}
1695
1700
1696
1701
fn atomic_fence ( & mut self , order : AtomicOrdering , scope : SynchronizationScope ) {
0 commit comments