about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_target/src/abi/call/x86_64.rs10
-rw-r--r--tests/ui/abi/issue-94223.rs8
2 files changed, 14 insertions, 4 deletions
diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs
index 74ef53915c9..b1aefaf0507 100644
--- a/compiler/rustc_target/src/abi/call/x86_64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_64.rs
@@ -153,9 +153,9 @@ fn reg_component(cls: &[Option<Class>], i: &mut usize, size: Size) -> Option<Reg
     }
 }
 
-fn cast_target(cls: &[Option<Class>], size: Size) -> CastTarget {
+fn cast_target(cls: &[Option<Class>], size: Size) -> Option<CastTarget> {
     let mut i = 0;
-    let lo = reg_component(cls, &mut i, size).unwrap();
+    let lo = reg_component(cls, &mut i, size)?;
     let offset = Size::from_bytes(8) * (i as u64);
     let mut target = CastTarget::from(lo);
     if size > offset {
@@ -164,7 +164,7 @@ fn cast_target(cls: &[Option<Class>], size: Size) -> CastTarget {
         }
     }
     assert_eq!(reg_component(cls, &mut i, Size::ZERO), None);
-    target
+    Some(target)
 }
 
 const MAX_INT_REGS: usize = 6; // RDI, RSI, RDX, RCX, R8, R9
@@ -227,7 +227,9 @@ where
                 // split into sized chunks passed individually
                 if arg.layout.is_aggregate() {
                     let size = arg.layout.size;
-                    arg.cast_to(cast_target(cls, size))
+                    if let Some(cast_target) = cast_target(cls, size) {
+                        arg.cast_to(cast_target);
+                    }
                 } else {
                     arg.extend_integer_width_to(32);
                 }
diff --git a/tests/ui/abi/issue-94223.rs b/tests/ui/abi/issue-94223.rs
new file mode 100644
index 00000000000..79d6b94031b
--- /dev/null
+++ b/tests/ui/abi/issue-94223.rs
@@ -0,0 +1,8 @@
+// check-pass
+#![allow(improper_ctypes_definitions)]
+#![crate_type = "lib"]
+
+// Check that computing the fn abi for `bad`, with a external ABI fn ptr that is not FFI-safe, does
+// not ICE.
+
+pub fn bad(f: extern "C" fn([u8])) {}