Skip to content

Commit 6ac1832

Browse files
authored
Unrolled build for #148240
Rollup merge of #148240 - InvalidPathException:master, r=WaffleLapkin rustc_codegen: fix musttail returns for cast/indirect ABIs Fixes #148239 #144986 Explicit tail calls trigger `bug!` for any callee whose ABI returns via `PassMode::Cast`, and we forgot to to forward the hidden `sret` out-pointer when the ABI requested an indirect return. The former causes ICE, the latter produced malformed IR (wrong codegen) if the return value is large enough to need `sret`. Updated the musttail helper to accept cast-mode returns, made it so that we pass the return pointer through the tail-call path. Added two UI tests to demonstrate each case. This is my first time contributing, please do check if I did it right. r? theemathas
2 parents c5dabe8 + 72c9762 commit 6ac1832

File tree

4 files changed

+56
-6
lines changed

4 files changed

+56
-6
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
1616
use rustc_codegen_ssa::traits::*;
1717
use rustc_data_structures::small_c_str::SmallCStr;
1818
use rustc_hir::def_id::DefId;
19-
use rustc_middle::bug;
2019
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
2120
use rustc_middle::ty::layout::{
2221
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
@@ -1458,10 +1457,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
14581457

14591458
match &fn_abi.ret.mode {
14601459
PassMode::Ignore | PassMode::Indirect { .. } => self.ret_void(),
1461-
PassMode::Direct(_) | PassMode::Pair { .. } => self.ret(call),
1462-
mode @ PassMode::Cast { .. } => {
1463-
bug!("Encountered `PassMode::{mode:?}` during codegen")
1464-
}
1460+
PassMode::Direct(_) | PassMode::Pair { .. } | PassMode::Cast { .. } => self.ret(call),
14651461
}
14661462
}
14671463

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10631063
let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs);
10641064
target.map(|target| (return_dest, target))
10651065
}
1066-
CallKind::Tail => None,
1066+
CallKind::Tail => {
1067+
if fn_abi.ret.is_indirect() {
1068+
match self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs) {
1069+
ReturnDest::Nothing => {}
1070+
_ => bug!(
1071+
"tail calls to functions with indirect returns cannot store into a destination"
1072+
),
1073+
}
1074+
}
1075+
None
1076+
}
10671077
};
10681078

10691079
// Split the rust-call tupled arguments off.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//@ run-pass
2+
//@ ignore-backends: gcc
3+
//@ ignore-wasm 'tail-call' feature not enabled in target wasm32-wasip1
4+
//@ ignore-cross-compile
5+
#![expect(incomplete_features)]
6+
#![feature(explicit_tail_calls)]
7+
8+
#[inline(never)]
9+
fn leaf(_: &Box<u8>) -> [u8; 1] {
10+
[1]
11+
}
12+
13+
#[inline(never)]
14+
fn dispatch(param: &Box<u8>) -> [u8; 1] {
15+
become leaf(param)
16+
}
17+
18+
fn main() {
19+
let data = Box::new(0);
20+
let out = dispatch(&data);
21+
assert_eq!(out, [1]);
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//@ run-pass
2+
//@ ignore-backends: gcc
3+
//@ ignore-wasm 'tail-call' feature not enabled in target wasm32-wasip1
4+
//@ ignore-cross-compile
5+
#![expect(incomplete_features)]
6+
#![feature(explicit_tail_calls)]
7+
8+
#[inline(never)]
9+
fn op_dummy(_param: &Box<u8>) -> [u8; 24] {
10+
[1; 24]
11+
}
12+
13+
#[inline(never)]
14+
fn dispatch(param: &Box<u8>) -> [u8; 24] {
15+
become op_dummy(param)
16+
}
17+
18+
fn main() {
19+
let param = Box::new(0);
20+
let result = dispatch(&param);
21+
assert_eq!(result, [1; 24]);
22+
}

0 commit comments

Comments
 (0)