Skip to content

Commit

Permalink
Merge pull request #585 from asomers/C-unwind
Browse files Browse the repository at this point in the history
Use the C-unwind ABI instead of C when mocking extern C functions
  • Loading branch information
asomers authored Jun 24, 2024
2 parents dc4a28f + b9cc253 commit bcb4a88
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ common: &COMMON
task:
name: MSRV
container:
image: rust:1.70.0
image: rust:1.71.0
cargo_lock_script:
- cp Cargo.lock.msrv Cargo.lock
<< : *COMMON
Expand Down
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,19 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Changed

- Raised MSRV to 1.70.0 to remove `lazy_static` dependency
([#550](https://github.com/asomers/mockall/pull/550))
- Raised MSRV to 1.71.0 due to the `C-unwind` ABI.
([#585](https://github.com/asomers/mockall/pull/585))

- No longer poison a Context object's internal `Mutex` when panicing. This
requires the "nightly" feature.
([#527](https://github.com/asomers/mockall/pull/527))

### Fixed

- Fixed panicing within mocked `extern "C"` functions, for example due to
unsatisfied expectations, with Rust 1.81.0 or newer.
([#585](https://github.com/asomers/mockall/pull/585))

## [ 0.12.1 ] - 2023-12-21

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ See the [API docs](https://docs.rs/mockall) for more information.

# Minimum Supported Rust Version (MSRV)

Mockall is supported on Rust 1.70.0 and higher. Mockall's MSRV will not be
Mockall is supported on Rust 1.71.0 and higher. Mockall's MSRV will not be
changed in the future without bumping the major or minor version.

# License
Expand Down
2 changes: 1 addition & 1 deletion mockall/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ categories = ["development-tools::testing"]
keywords = ["mock", "mocking", "testing"]
documentation = "https://docs.rs/mockall"
edition = "2021"
rust-version = "1.70"
rust-version = "1.71"
description = """
A powerful mock object library for Rust.
"""
Expand Down
2 changes: 1 addition & 1 deletion mockall/tests/automock_foreign_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ fn c_abi() {
let _m = FOO_MTX.lock();
let ctx = mock_ffi::foo_context();
ctx.expect().returning(i64::from);
let p: unsafe extern "C" fn(u32) -> i64 = mock_ffi::foo;
let p: unsafe extern "C-unwind" fn(u32) -> i64 = mock_ffi::foo;
assert_eq!(42, unsafe{p(42)});
}
13 changes: 13 additions & 0 deletions mockall/tests/automock_foreign_c_variadic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,24 @@ pub mod ffi {
}
}

#[cfg(feature = "nightly")]
static FOO_MTX: std::sync::Mutex<()> = std::sync::Mutex::new(());

#[test]
#[cfg(feature = "nightly")]
#[cfg_attr(miri, ignore)]
fn mocked_c_variadic() {
let _m = FOO_MTX.lock();
let ctx = mock_ffi::foo_context();
ctx.expect().returning(|x, y| x * y);
assert_eq!(6, unsafe{mock_ffi::foo(2, 3, 1, 4, 1)});
}

#[test]
#[cfg(feature = "nightly")]
#[cfg_attr(miri, ignore)]
#[ignore = "https://github.com/rust-lang/rust/issues/126836"]
fn panics() {
let _m = FOO_MTX.lock();
unsafe{ mock_ffi::foo(1,2,3) };
}
23 changes: 22 additions & 1 deletion mockall_derive/src/mock_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,28 @@ impl From<MockableModule> for MockItemModule {

// Set the ABI to match the ForeignMod's ABI
// for proper function linkage with external code.
f.sig.abi = Some(ifm.abi.clone());
//
// BUT, use C-unwind instead of C, so we can panic
// from the mock function (rust-lang/rust #74990)
//
// BUT, don't use C-unwind for variadic functions,
// because it doesn't work yet (rust-lang/rust
// #126836)
let needs_c_unwind = if let Some(n) = &ifm.abi.name
{
n.value() == "C" && f.sig.variadic.is_none()
} else {
false
};
f.sig.abi = Some(if needs_c_unwind {
Abi {
extern_token:ifm.abi.extern_token,
name: Some(LitStr::new("C-unwind",
ifm.abi.name.span()))
}
} else {
ifm.abi.clone()
});

let mf = mock_function::Builder::new(&f.sig, &f.vis)
.attrs(&f.attrs)
Expand Down

0 comments on commit bcb4a88

Please sign in to comment.