Thanks for your crates. There is a potential unsoundness, which can trigger UB in safe public API.
AtomPtr::compare_exchange returns a Ref<T> that owns the currently stored Box<Arc<T>> even on CAS failure; dropping that Ref and later dropping the AtomPtr frees the same pointer twice (double‐free).
use atomptr::AtomPtr;
fn main() {
// Create an AtomPtr, take a Ref to the current value.
let ptr = AtomPtr::new(String::from("a"));
let prev = ptr.get_ref();
// Change the stored pointer so `prev` becomes stale.
let _old = ptr.swap(String::from("b"));
// This compare_exchange must fail, and returns a Ref that owns
// the *current* pointer still stored inside AtomPtr.
let res = ptr.compare_exchange(prev, String::from("c"));
let current = res.inner();
}
miri outputs:
error: Undefined Behavior: constructing invalid value: encountered a dangling box (use-after-free)
--> /Users/yxz/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1493:9
|
1493 | Box(unsafe { Unique::new_unchecked(raw) }, alloc)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: stack backtrace:
0: std::boxed::Box::<std::sync::Arc<std::string::String>>::from_raw_in
at /Users/yxz/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1493:9: 1493:58
1: std::boxed::Box::<std::sync::Arc<std::string::String>>::from_raw
at /Users/yxz/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1266:18: 1266:48
2: <atomptr::AtomPtr<std::string::String> as std::ops::Drop>::drop
at /Users/yxz/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atomptr-3.2.0/src/pointer.rs:30:31: 30:49
3: std::ptr::drop_in_place::<atomptr::AtomPtr<std::string::String>> - shim(Some(atomptr::AtomPtr<std::string::String>))
at /Users/yxz/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
4: main
at src/main.rs:15:1: 15:2
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 1 previous error; 1 warning emitted