Skip to content

Commit 812d9ad

Browse files
authored
Merge pull request #4496 from RalfJung/ctor-ret-type
call_function helper: dont ICE on return type mismatches
2 parents 94ce66d + ddaff80 commit 812d9ad

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

src/tools/miri/src/helpers.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
437437
/// For now, arguments must be scalars (so that the caller does not have to know the layout).
438438
///
439439
/// If you do not provide a return place, a dangling zero-sized place will be created
440-
/// for your convenience.
440+
/// for your convenience. This is only valid if the return type is `()`.
441441
fn call_function(
442442
&mut self,
443443
f: ty::Instance<'tcx>,
@@ -452,7 +452,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
452452
let mir = this.load_mir(f.def, None)?;
453453
let dest = match dest {
454454
Some(dest) => dest.clone(),
455-
None => MPlaceTy::fake_alloc_zst(this.layout_of(mir.return_ty())?),
455+
None => MPlaceTy::fake_alloc_zst(this.machine.layouts.unit),
456456
};
457457

458458
// Construct a function pointer type representing the caller perspective.
@@ -465,6 +465,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
465465
);
466466
let caller_fn_abi = this.fn_abi_of_fn_ptr(ty::Binder::dummy(sig), ty::List::empty())?;
467467

468+
// This will also show proper errors if there is any ABI mismatch.
468469
this.init_stack_frame(
469470
f,
470471
mir,
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
unsafe extern "C" fn ctor() -> i32 {
2+
//~^ERROR: calling a function with return type i32 passing return place of type ()
3+
0
4+
}
5+
6+
#[rustfmt::skip]
7+
macro_rules! ctor {
8+
($ident:ident = $ctor:ident) => {
9+
#[cfg_attr(
10+
all(any(
11+
target_os = "linux",
12+
target_os = "android",
13+
target_os = "dragonfly",
14+
target_os = "freebsd",
15+
target_os = "haiku",
16+
target_os = "illumos",
17+
target_os = "netbsd",
18+
target_os = "openbsd",
19+
target_os = "solaris",
20+
target_os = "none",
21+
target_family = "wasm",
22+
)),
23+
link_section = ".init_array"
24+
)]
25+
#[cfg_attr(windows, link_section = ".CRT$XCU")]
26+
#[cfg_attr(
27+
any(target_os = "macos", target_os = "ios"),
28+
// We do not set the `mod_init_funcs` flag here since ctor/inventory also do not do
29+
// that. See <https://github.com/rust-lang/miri/pull/4459#discussion_r2200115629>.
30+
link_section = "__DATA,__mod_init_func"
31+
)]
32+
#[used]
33+
static $ident: unsafe extern "C" fn() -> i32 = $ctor;
34+
};
35+
}
36+
37+
ctor! { CTOR = ctor }
38+
39+
fn main() {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error: Undefined Behavior: calling a function with return type i32 passing return place of type ()
2+
|
3+
= note: Undefined Behavior occurred here
4+
= note: (no span available)
5+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
6+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
7+
= help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
8+
= help: if you think this code should be accepted anyway, please report an issue with Miri
9+
= note: BACKTRACE:
10+
11+
error: aborting due to 1 previous error
12+

0 commit comments

Comments
 (0)