Skip to content

Commit f4c9597

Browse files
committed
Use ManuallyDrop<T> instead of mem::forget in scopeguard
With field retagging in SB, this causes UB because the read out value is invalidated by the move into `mem::forget`. Using `ManuallyDrop<T>` avoids the problem.
1 parent 22c7dbc commit f4c9597

File tree

1 file changed

+6
-8
lines changed

1 file changed

+6
-8
lines changed

src/scopeguard.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Extracted from the scopeguard crate
22
use core::{
3-
mem,
3+
mem::ManuallyDrop,
44
ops::{Deref, DerefMut},
55
ptr,
66
};
@@ -28,15 +28,13 @@ where
2828
#[inline]
2929
pub fn into_inner(guard: Self) -> T {
3030
// Cannot move out of Drop-implementing types, so
31-
// ptr::read the value and forget the guard.
31+
// ptr::read the value out of a ManuallyDrop<Self>
32+
// Don't use mem::forget as that might invalidate value
33+
let guard = ManuallyDrop::new(guard);
3234
unsafe {
3335
let value = ptr::read(&guard.value);
34-
// read the closure so that it is dropped, and assign it to a local
35-
// variable to ensure that it is only dropped after the guard has
36-
// been forgotten. (In case the Drop impl of the closure, or that
37-
// of any consumed captured variable, panics).
38-
let _dropfn = ptr::read(&guard.dropfn);
39-
mem::forget(guard);
36+
// read the closure so that it is dropped
37+
let _ = ptr::read(&guard.dropfn);
4038
value
4139
}
4240
}

0 commit comments

Comments
 (0)