Skip to content

Commit c8f0b15

Browse files
committed
Make fn_abi_sanity_check a bit stricter
The Rust ABI must ignore all ZST arguments, all ignored arguments must be either ZST or uninhabited. And finally ScalarPair should never be passed as PassMode::Direct.
1 parent fe43131 commit c8f0b15

File tree

1 file changed

+51
-30
lines changed
  • compiler/rustc_ty_utils/src

1 file changed

+51
-30
lines changed

compiler/rustc_ty_utils/src/abi.rs

+51-30
Original file line numberDiff line numberDiff line change
@@ -463,43 +463,64 @@ fn fn_abi_sanity_check<'tcx>(
463463
arg: &ArgAbi<'tcx, Ty<'tcx>>,
464464
) {
465465
let tcx = cx.tcx();
466+
467+
if spec_abi == ExternAbi::Rust
468+
|| spec_abi == ExternAbi::RustCall
469+
|| spec_abi == ExternAbi::RustCold
470+
{
471+
if arg.layout.is_zst() {
472+
// Casting closures to function pointers depends on ZST closure types being
473+
// omitted entirely in the calling convention.
474+
assert!(arg.is_ignore());
475+
}
476+
if let PassMode::Indirect { on_stack, .. } = arg.mode {
477+
assert!(!on_stack, "rust abi shouldn't use on_stack");
478+
}
479+
}
480+
466481
match &arg.mode {
467-
PassMode::Ignore => {}
482+
PassMode::Ignore => {
483+
assert!(arg.layout.is_zst() || arg.layout.is_uninhabited());
484+
}
468485
PassMode::Direct(_) => {
469486
// Here the Rust type is used to determine the actual ABI, so we have to be very
470-
// careful. Scalar/ScalarPair is fine, since backends will generally use
471-
// `layout.abi` and ignore everything else. We should just reject `Aggregate`
472-
// entirely here, but some targets need to be fixed first.
473-
if matches!(arg.layout.backend_repr, BackendRepr::Memory { .. }) {
474-
// For an unsized type we'd only pass the sized prefix, so there is no universe
475-
// in which we ever want to allow this.
476-
assert!(
477-
arg.layout.is_sized(),
478-
"`PassMode::Direct` for unsized type in ABI: {:#?}",
479-
fn_abi
480-
);
481-
// This really shouldn't happen even for sized aggregates, since
482-
// `immediate_llvm_type` will use `layout.fields` to turn this Rust type into an
483-
// LLVM type. This means all sorts of Rust type details leak into the ABI.
484-
// However wasm sadly *does* currently use this mode so we have to allow it --
485-
// but we absolutely shouldn't let any more targets do that.
486-
// (Also see <https://github.com/rust-lang/rust/issues/115666>.)
487-
//
488-
// The unstable abi `PtxKernel` also uses Direct for now.
489-
// It needs to switch to something else before stabilization can happen.
490-
// (See issue: https://github.com/rust-lang/rust/issues/117271)
491-
assert!(
492-
matches!(&*tcx.sess.target.arch, "wasm32" | "wasm64")
493-
|| matches!(spec_abi, ExternAbi::PtxKernel | ExternAbi::Unadjusted),
494-
"`PassMode::Direct` for aggregates only allowed for \"unadjusted\" and \"ptx-kernel\" functions and on wasm\n\
487+
// careful. Scalar/Vector is fine, since backends will generally use
488+
// `layout.backend_repr` and ignore everything else. We should just reject
489+
//`Aggregate` entirely here, but some targets need to be fixed first.
490+
match arg.layout.backend_repr {
491+
BackendRepr::Uninhabited
492+
| BackendRepr::Scalar(_)
493+
| BackendRepr::Vector { .. } => {}
494+
BackendRepr::ScalarPair(..) => {
495+
panic!("`PassMode::Direct` used for ScalarPair type {}", arg.layout.ty)
496+
}
497+
BackendRepr::Memory { sized } => {
498+
// For an unsized type we'd only pass the sized prefix, so there is no universe
499+
// in which we ever want to allow this.
500+
assert!(sized, "`PassMode::Direct` for unsized type in ABI: {:#?}", fn_abi);
501+
// This really shouldn't happen even for sized aggregates, since
502+
// `immediate_llvm_type` will use `layout.fields` to turn this Rust type into an
503+
// LLVM type. This means all sorts of Rust type details leak into the ABI.
504+
// However wasm sadly *does* currently use this mode so we have to allow it --
505+
// but we absolutely shouldn't let any more targets do that.
506+
// (Also see <https://github.com/rust-lang/rust/issues/115666>.)
507+
//
508+
// The unstable abi `PtxKernel` also uses Direct for now.
509+
// It needs to switch to something else before stabilization can happen.
510+
// (See issue: https://github.com/rust-lang/rust/issues/117271)
511+
assert!(
512+
matches!(&*tcx.sess.target.arch, "wasm32" | "wasm64")
513+
|| matches!(spec_abi, ExternAbi::PtxKernel | ExternAbi::Unadjusted),
514+
"`PassMode::Direct` for aggregates only allowed for \"unadjusted\" and \"ptx-kernel\" functions and on wasm\n\
495515
Problematic type: {:#?}",
496-
arg.layout,
497-
);
516+
arg.layout,
517+
);
518+
}
498519
}
499520
}
500521
PassMode::Pair(_, _) => {
501-
// Similar to `Direct`, we need to make sure that backends use `layout.abi` and
502-
// ignore the rest of the layout.
522+
// Similar to `Direct`, we need to make sure that backends use `layout.backend_repr`
523+
// and ignore the rest of the layout.
503524
assert!(
504525
matches!(arg.layout.backend_repr, BackendRepr::ScalarPair(..)),
505526
"PassMode::Pair for type {}",

0 commit comments

Comments
 (0)