Skip to content

Commit 09fff5f

Browse files
committed
Disable Atomic*::from_mut when alignment is wrong.
1 parent fcf1571 commit 09fff5f

File tree

1 file changed

+35
-4
lines changed

1 file changed

+35
-4
lines changed

library/core/src/sync/atomic.rs

+35-4
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ use self::Ordering::*;
121121
use crate::cell::UnsafeCell;
122122
use crate::fmt;
123123
use crate::intrinsics;
124+
use crate::mem::align_of;
124125

125126
use 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")]
12801292
macro_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

Comments
 (0)