Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit bcb4a88

Browse files
authoredJun 24, 2024··
Merge pull request #585 from asomers/C-unwind
Use the C-unwind ABI instead of C when mocking extern C functions
2 parents dc4a28f + b9cc253 commit bcb4a88

File tree

7 files changed

+47
-7
lines changed

7 files changed

+47
-7
lines changed
 

‎.cirrus.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ common: &COMMON
1414
task:
1515
name: MSRV
1616
container:
17-
image: rust:1.70.0
17+
image: rust:1.71.0
1818
cargo_lock_script:
1919
- cp Cargo.lock.msrv Cargo.lock
2020
<< : *COMMON

‎CHANGELOG.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1313

1414
### Changed
1515

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

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

23+
### Fixed
24+
25+
- Fixed panicing within mocked `extern "C"` functions, for example due to
26+
unsatisfied expectations, with Rust 1.81.0 or newer.
27+
([#585](https://github.com/asomers/mockall/pull/585))
28+
2329
## [ 0.12.1 ] - 2023-12-21
2430

2531
### Fixed

‎README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ See the [API docs](https://docs.rs/mockall) for more information.
6262

6363
# Minimum Supported Rust Version (MSRV)
6464

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

6868
# License

‎mockall/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ categories = ["development-tools::testing"]
99
keywords = ["mock", "mocking", "testing"]
1010
documentation = "https://docs.rs/mockall"
1111
edition = "2021"
12-
rust-version = "1.70"
12+
rust-version = "1.71"
1313
description = """
1414
A powerful mock object library for Rust.
1515
"""

‎mockall/tests/automock_foreign_c.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ fn c_abi() {
4747
let _m = FOO_MTX.lock();
4848
let ctx = mock_ffi::foo_context();
4949
ctx.expect().returning(i64::from);
50-
let p: unsafe extern "C" fn(u32) -> i64 = mock_ffi::foo;
50+
let p: unsafe extern "C-unwind" fn(u32) -> i64 = mock_ffi::foo;
5151
assert_eq!(42, unsafe{p(42)});
5252
}

‎mockall/tests/automock_foreign_c_variadic.rs

+13
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,24 @@ pub mod ffi {
1313
}
1414
}
1515

16+
#[cfg(feature = "nightly")]
17+
static FOO_MTX: std::sync::Mutex<()> = std::sync::Mutex::new(());
18+
1619
#[test]
1720
#[cfg(feature = "nightly")]
1821
#[cfg_attr(miri, ignore)]
1922
fn mocked_c_variadic() {
23+
let _m = FOO_MTX.lock();
2024
let ctx = mock_ffi::foo_context();
2125
ctx.expect().returning(|x, y| x * y);
2226
assert_eq!(6, unsafe{mock_ffi::foo(2, 3, 1, 4, 1)});
2327
}
28+
29+
#[test]
30+
#[cfg(feature = "nightly")]
31+
#[cfg_attr(miri, ignore)]
32+
#[ignore = "https://github.com/rust-lang/rust/issues/126836"]
33+
fn panics() {
34+
let _m = FOO_MTX.lock();
35+
unsafe{ mock_ffi::foo(1,2,3) };
36+
}

‎mockall_derive/src/mock_item.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,28 @@ impl From<MockableModule> for MockItemModule {
9595

9696
// Set the ABI to match the ForeignMod's ABI
9797
// for proper function linkage with external code.
98-
f.sig.abi = Some(ifm.abi.clone());
98+
//
99+
// BUT, use C-unwind instead of C, so we can panic
100+
// from the mock function (rust-lang/rust #74990)
101+
//
102+
// BUT, don't use C-unwind for variadic functions,
103+
// because it doesn't work yet (rust-lang/rust
104+
// #126836)
105+
let needs_c_unwind = if let Some(n) = &ifm.abi.name
106+
{
107+
n.value() == "C" && f.sig.variadic.is_none()
108+
} else {
109+
false
110+
};
111+
f.sig.abi = Some(if needs_c_unwind {
112+
Abi {
113+
extern_token:ifm.abi.extern_token,
114+
name: Some(LitStr::new("C-unwind",
115+
ifm.abi.name.span()))
116+
}
117+
} else {
118+
ifm.abi.clone()
119+
});
99120

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

0 commit comments

Comments
 (0)
Please sign in to comment.