Skip to content

Commit 225796a

Browse files
committed
Add method to get FnAbi of function pointer
1 parent 4e6de37 commit 225796a

4 files changed

Lines changed: 44 additions & 1 deletion

File tree

‎compiler/rustc_smir/src/rustc_smir/context.rs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
533533
Ok(tables.fn_abi_of_instance(instance,List::empty())?.stable(&mut*tables))
534534
}
535535

536+
fnfn_ptr_abi(&self,fn_ptr:PolyFnSig) -> Result<FnAbi,Error>{
537+
letmut tables = self.0.borrow_mut();
538+
let tcx = tables.tcx;
539+
let sig = fn_ptr.internal(&mut*tables, tcx);
540+
Ok(tables.fn_abi_of_fn_ptr(sig,List::empty())?.stable(&mut*tables))
541+
}
542+
536543
fninstance_def_id(&self,def:InstanceDef) -> stable_mir::DefId{
537544
letmut tables = self.0.borrow_mut();
538545
let def_id = tables.instances[def].def_id();

‎compiler/stable_mir/src/compiler_interface.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ pub trait Context {
215215
/// Get an instance ABI.
216216
fninstance_abi(&self,def:InstanceDef) -> Result<FnAbi,Error>;
217217

218+
/// Get the ABI of a function pointer.
219+
fnfn_ptr_abi(&self,fn_ptr:PolyFnSig) -> Result<FnAbi,Error>;
220+
218221
/// Get the layout of a type.
219222
fnty_layout(&self,ty:Ty) -> Result<Layout,Error>;
220223

‎compiler/stable_mir/src/ty.rs‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::{
22
mir::{Body,Mutability,Safety},
33
with,DefId,Error,Symbol,
44
};
5-
usecrate::abi::Layout;
5+
usecrate::abi::{FnAbi,Layout};
66
usecrate::crate_def::{CrateDef,CrateDefType};
77
usecrate::mir::alloc::{read_target_int, read_target_uint,AllocId};
88
usecrate::mir::mono::StaticDef;
@@ -996,6 +996,16 @@ pub struct AliasTerm {
996996

997997
pubtypePolyFnSig = Binder<FnSig>;
998998

999+
implPolyFnSig{
1000+
/// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
1001+
///
1002+
/// NB: this doesn't handle virtual calls - those should use `Instance::fn_abi`
1003+
/// instead, where the instance is an `InstanceKind::Virtual`.
1004+
pubfnfn_ptr_abi(self) -> Result<FnAbi,Error>{
1005+
with(|cx| cx.fn_ptr_abi(self))
1006+
}
1007+
}
1008+
9991009
#[derive(Clone,Debug,Eq,PartialEq)]
10001010
pubstructFnSig{
10011011
pubinputs_and_output:Vec<Ty>,

‎tests/ui-fulldeps/stable-mir/check_abi.rs‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@ fn test_stable_mir() -> ControlFlow<()> {
5454
let variadic_fn = *get_item(&items,(ItemKind::Fn,"variadic_fn")).unwrap();
5555
check_variadic(variadic_fn);
5656

57+
// Extract function pointers.
58+
let fn_ptr_holder = *get_item(&items,(ItemKind::Fn,"fn_ptr_holder")).unwrap();
59+
let fn_ptr_holder_instance = Instance::try_from(fn_ptr_holder).unwrap();
60+
let body = fn_ptr_holder_instance.body().unwrap();
61+
let args = body.arg_locals();
62+
63+
// Test fn_abi of function pointer version.
64+
let ptr_fn_abi = args[0].ty.kind().fn_sig().unwrap().fn_ptr_abi().unwrap();
65+
assert_eq!(ptr_fn_abi, fn_abi);
66+
67+
// Test variadic_fn of function pointer version.
68+
let ptr_variadic_fn_abi = args[1].ty.kind().fn_sig().unwrap().fn_ptr_abi().unwrap();
69+
assert!(ptr_variadic_fn_abi.c_variadic);
70+
assert_eq!(ptr_variadic_fn_abi.args.len(),1);
71+
5772
ControlFlow::Continue(())
5873
}
5974

@@ -164,6 +179,14 @@ fn generate_input(path: &str) -> std::io::Result<()> {
164179
pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) -> usize {{
165180
0
166181
}}
182+
183+
pub type ComplexFn = fn([u8; 0], char, NonZero<u8>) -> Result<usize, &'static str>;
184+
pub type VariadicFn = unsafe extern "C" fn(usize, ...) -> usize;
185+
186+
pub fn fn_ptr_holder(complex_fn: ComplexFn, variadic_fn: VariadicFn) {{
187+
// We only care about the signature.
188+
todo!()
189+
}}
167190
"#
168191
)?;
169192
Ok(())

0 commit comments

Comments
 (0)