Skip to content

Commit

Permalink
Merge pull request #1372 from dtolnay/unwind
Browse files Browse the repository at this point in the history
Hide the UnsafeCell content of opaque C++ types in regard to unwind safety
  • Loading branch information
dtolnay authored Aug 30, 2024
2 parents 86f1f71 + ced1e7d commit aa9abc7
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::void;
use core::cell::UnsafeCell;
use core::marker::{PhantomData, PhantomPinned};
use core::mem;
use core::panic::RefUnwindSafe;

// . size = 0
// . align = 1
Expand All @@ -12,13 +13,16 @@ use core::mem;
// . !Sync
// . !Unpin
// . not readonly
// . unwind-safe
#[repr(C, packed)]
pub struct Opaque {
_private: [*const void; 0],
_pinned: PhantomData<PhantomPinned>,
_mutable: SyncUnsafeCell<PhantomData<()>>,
}

impl RefUnwindSafe for Opaque {}

// TODO: https://github.com/rust-lang/rust/issues/95439
#[repr(transparent)]
struct SyncUnsafeCell<T>(UnsafeCell<T>);
Expand Down
17 changes: 16 additions & 1 deletion tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
clippy::unseparated_literal_suffix
)]

use cxx::SharedPtr;
use cxx::{SharedPtr, UniquePtr};
use cxx_test_suite::module::ffi2;
use cxx_test_suite::{cast, ffi, R};
use std::cell::Cell;
use std::ffi::CStr;
use std::panic::{self, RefUnwindSafe, UnwindSafe};

thread_local! {
static CORRECT: Cell<bool> = const { Cell::new(false) };
Expand Down Expand Up @@ -380,3 +381,17 @@ fn test_raw_ptr() {
assert_eq!(2025, unsafe { ffi::c_take_const_ptr(c3) });
assert_eq!(2025, unsafe { ffi::c_take_mut_ptr(c3 as *mut ffi::C) }); // deletes c3
}

#[test]
#[allow(clippy::items_after_statements, clippy::no_effect_underscore_binding)]
fn test_unwind_safe() {
fn inspect(_c: &ffi::C) {}
let _unwind_safe = |c: UniquePtr<ffi::C>| panic::catch_unwind(|| drop(c));
let _ref_unwind_safe = |c: &ffi::C| panic::catch_unwind(|| inspect(c));

fn require_unwind_safe<T: UnwindSafe>() {}
require_unwind_safe::<ffi::C>();

fn require_ref_unwind_safe<T: RefUnwindSafe>() {}
require_ref_unwind_safe::<ffi::C>();
}

0 comments on commit aa9abc7

Please sign in to comment.