@@ -121,6 +121,7 @@ use self::Ordering::*;
121121use crate :: cell:: UnsafeCell ;
122122use crate :: fmt;
123123use crate :: intrinsics;
124+ use crate :: mem:: align_of;
124125
125126use crate :: hint:: spin_loop;
126127
@@ -374,7 +375,8 @@ impl AtomicBool {
374375 #[ inline]
375376 #[ unstable( feature = "atomic_from_mut" , issue = "none" ) ]
376377 pub fn from_mut ( v : & mut bool ) -> & Self {
377- // SAFETY: the mutable reference guarantees unique ownership.
378+ // SAFETY: the mutable reference guarantees unique ownership, and
379+ // alignment of both `bool` and `Self` is 1.
378380 unsafe { & * ( v as * mut bool as * mut Self ) }
379381 }
380382
@@ -950,7 +952,11 @@ impl<T> AtomicPtr<T> {
950952 #[ inline]
951953 #[ unstable( feature = "atomic_from_mut" , issue = "none" ) ]
952954 pub fn from_mut ( v : & mut * mut T ) -> & Self {
953- // SAFETY: the mutable reference guarantees unique ownership,
955+ let [ ] = [ ( ) ; align_of :: < Self > ( ) - align_of :: < * mut T > ( ) ] ;
956+ // SAFETY:
957+ // - the mutable reference guarantees unique ownership.
958+ // - the alignment of `*mut T` and `Self` is the same on all platforms
959+ // supported by rust, as verified above.
954960 unsafe { & * ( v as * mut * mut T as * mut Self ) }
955961 }
956962
@@ -1276,6 +1282,12 @@ impl<T> From<*mut T> for AtomicPtr<T> {
12761282 }
12771283}
12781284
1285+ macro_rules! if_not_8_bit {
1286+ ( u8 , $( $tt: tt) * ) => { "" } ;
1287+ ( i8 , $( $tt: tt) * ) => { "" } ;
1288+ ( $_: ident, $( $tt: tt) * ) => { $( $tt) * } ;
1289+ }
1290+
12791291#[ cfg( target_has_atomic_load_store = "8" ) ]
12801292macro_rules! atomic_int {
12811293 ( $cfg_cas: meta,
@@ -1287,7 +1299,8 @@ macro_rules! atomic_int {
12871299 $stable_nand: meta,
12881300 $const_stable: meta,
12891301 $stable_init_const: meta,
1290- $s_int_type: expr, $int_ref: expr,
1302+ $( from_mut: cfg( $from_mut_cfg: meta) , ) ?
1303+ $s_int_type: literal, $int_ref: expr,
12911304 $extra_feature: expr,
12921305 $min_fn: ident, $max_fn: ident,
12931306 $align: expr,
@@ -1401,6 +1414,16 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5);
14011414 doc_comment! {
14021415 concat!( "Get atomic access to a `&mut " , stringify!( $int_type) , "`.
14031416
1417+ " ,
1418+ if_not_8_bit! {
1419+ $int_type,
1420+ concat!(
1421+ "**Note:** This function is only available on targets where `" ,
1422+ stringify!( $int_type) , "` has an alignment of " , $align, " bytes."
1423+ )
1424+ } ,
1425+ "
1426+
14041427# Examples
14051428
14061429```
@@ -1414,9 +1437,15 @@ assert_eq!(some_int, 100);
14141437```
14151438 " ) ,
14161439 #[ inline]
1440+ $( #[ cfg( $from_mut_cfg) ] ) ?
14171441 #[ unstable( feature = "atomic_from_mut" , issue = "none" ) ]
14181442 pub fn from_mut( v: & mut $int_type) -> & Self {
1419- // SAFETY: the mutable reference guarantees unique ownership.
1443+ let [ ] = [ ( ) ; align_of:: <Self >( ) - align_of:: <$int_type>( ) ] ;
1444+ // SAFETY:
1445+ // - the mutable reference guarantees unique ownership.
1446+ // - the alignment of `$int_type` and `Self` is the
1447+ // same on all platforms enabled by `$from_mut_cfg`
1448+ // as verified above.
14201449 unsafe { & * ( v as * mut $int_type as * mut Self ) }
14211450 }
14221451 }
@@ -2265,6 +2294,7 @@ atomic_int! {
22652294 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
22662295 rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
22672296 unstable( feature = "integer_atomics" , issue = "32976" ) ,
2297+ from_mut: cfg( not( target_arch = "x86" ) ) ,
22682298 "i64" , "../../../std/primitive.i64.html" ,
22692299 "" ,
22702300 atomic_min, atomic_max,
@@ -2283,6 +2313,7 @@ atomic_int! {
22832313 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
22842314 rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
22852315 unstable( feature = "integer_atomics" , issue = "32976" ) ,
2316+ from_mut: cfg( not( target_arch = "x86" ) ) ,
22862317 "u64" , "../../../std/primitive.u64.html" ,
22872318 "" ,
22882319 atomic_umin, atomic_umax,
0 commit comments