Skip to content

Commit aa9abc7

Browse files
authored
Merge pull request #1372 from dtolnay/unwind
Hide the UnsafeCell content of opaque C++ types in regard to unwind safety
2 parents 86f1f71 + ced1e7d commit aa9abc7

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

src/opaque.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::void;
44
use core::cell::UnsafeCell;
55
use core::marker::{PhantomData, PhantomPinned};
66
use core::mem;
7+
use core::panic::RefUnwindSafe;
78

89
// . size = 0
910
// . align = 1
@@ -12,13 +13,16 @@ use core::mem;
1213
// . !Sync
1314
// . !Unpin
1415
// . not readonly
16+
// . unwind-safe
1517
#[repr(C, packed)]
1618
pub struct Opaque {
1719
_private: [*const void; 0],
1820
_pinned: PhantomData<PhantomPinned>,
1921
_mutable: SyncUnsafeCell<PhantomData<()>>,
2022
}
2123

24+
impl RefUnwindSafe for Opaque {}
25+
2226
// TODO: https://github.com/rust-lang/rust/issues/95439
2327
#[repr(transparent)]
2428
struct SyncUnsafeCell<T>(UnsafeCell<T>);

tests/test.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
clippy::unseparated_literal_suffix
1212
)]
1313

14-
use cxx::SharedPtr;
14+
use cxx::{SharedPtr, UniquePtr};
1515
use cxx_test_suite::module::ffi2;
1616
use cxx_test_suite::{cast, ffi, R};
1717
use std::cell::Cell;
1818
use std::ffi::CStr;
19+
use std::panic::{self, RefUnwindSafe, UnwindSafe};
1920

2021
thread_local! {
2122
static CORRECT: Cell<bool> = const { Cell::new(false) };
@@ -380,3 +381,17 @@ fn test_raw_ptr() {
380381
assert_eq!(2025, unsafe { ffi::c_take_const_ptr(c3) });
381382
assert_eq!(2025, unsafe { ffi::c_take_mut_ptr(c3 as *mut ffi::C) }); // deletes c3
382383
}
384+
385+
#[test]
386+
#[allow(clippy::items_after_statements, clippy::no_effect_underscore_binding)]
387+
fn test_unwind_safe() {
388+
fn inspect(_c: &ffi::C) {}
389+
let _unwind_safe = |c: UniquePtr<ffi::C>| panic::catch_unwind(|| drop(c));
390+
let _ref_unwind_safe = |c: &ffi::C| panic::catch_unwind(|| inspect(c));
391+
392+
fn require_unwind_safe<T: UnwindSafe>() {}
393+
require_unwind_safe::<ffi::C>();
394+
395+
fn require_ref_unwind_safe<T: RefUnwindSafe>() {}
396+
require_ref_unwind_safe::<ffi::C>();
397+
}

0 commit comments

Comments
 (0)