Skip to content

Commit e1502e7

Browse files
committed
Start migrating foreign function
1 parent 6b2b5cf commit e1502e7

File tree

2 files changed

+22
-52
lines changed

2 files changed

+22
-52
lines changed

kani-compiler/src/codegen_cprover_gotoc/codegen/foreign_function.rs

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ use crate::kani_middle;
1515
use cbmc::goto_program::{Expr, Location, Stmt, Symbol, Type};
1616
use cbmc::{InternString, InternedString};
1717
use lazy_static::lazy_static;
18-
use rustc_middle::ty::Instance;
1918
use rustc_smir::rustc_internal;
2019
use rustc_target::abi::call::Conv;
21-
use stable_mir::mir::mono::Instance as InstanceStable;
20+
use stable_mir::mir::mono::Instance;
21+
use stable_mir::CrateDef;
2222
use tracing::{debug, trace};
2323

2424
lazy_static! {
@@ -46,15 +46,16 @@ impl<'tcx> GotocCtx<'tcx> {
4646
///
4747
/// For other foreign items, we declare a shim and add to the list of foreign shims to be
4848
/// handled later.
49-
pub fn codegen_foreign_fn(&mut self, instance: InstanceStable) -> &Symbol {
49+
pub fn codegen_foreign_fn(&mut self, instance: Instance) -> &Symbol {
5050
debug!(?instance, "codegen_foreign_function");
51-
let instance = rustc_internal::internal(instance);
52-
let fn_name = self.symbol_name(instance).intern();
51+
let internal_instance = rustc_internal::internal(instance);
52+
let fn_name = self.symbol_name_stable(instance).intern();
5353
if self.symbol_table.contains(fn_name) {
5454
// Symbol has been added (either a built-in CBMC function or a Rust allocation function).
5555
self.symbol_table.lookup(fn_name).unwrap()
5656
} else if RUST_ALLOC_FNS.contains(&fn_name)
57-
|| (self.is_cffi_enabled() && kani_middle::fn_abi(self.tcx, instance).conv == Conv::C)
57+
|| (self.is_cffi_enabled()
58+
&& kani_middle::fn_abi(self.tcx, internal_instance).conv == Conv::C)
5859
{
5960
// Add a Rust alloc lib function as is declared by core.
6061
// When C-FFI feature is enabled, we just trust the rust declaration.
@@ -63,14 +64,8 @@ impl<'tcx> GotocCtx<'tcx> {
6364
// https://github.com/model-checking/kani/issues/2426
6465
self.ensure(fn_name, |gcx, _| {
6566
let typ = gcx.codegen_ffi_type(instance);
66-
Symbol::function(
67-
fn_name,
68-
typ,
69-
None,
70-
gcx.readable_instance_name(instance),
71-
Location::none(),
72-
)
73-
.with_is_extern(true)
67+
Symbol::function(fn_name, typ, None, instance.name(), Location::none())
68+
.with_is_extern(true)
7469
})
7570
} else {
7671
let shim_name = format!("{fn_name}_ffi_shim");
@@ -82,7 +77,7 @@ impl<'tcx> GotocCtx<'tcx> {
8277
&shim_name,
8378
typ,
8479
Some(gcx.codegen_ffi_shim(shim_name.as_str().into(), instance)),
85-
gcx.readable_instance_name(instance),
80+
instance.name(),
8681
Location::none(),
8782
)
8883
})
@@ -96,19 +91,19 @@ impl<'tcx> GotocCtx<'tcx> {
9691
}
9792

9893
/// Generate code for a foreign function shim.
99-
fn codegen_ffi_shim(&mut self, shim_name: InternedString, instance: Instance<'tcx>) -> Stmt {
94+
fn codegen_ffi_shim(&mut self, shim_name: InternedString, instance: Instance) -> Stmt {
10095
debug!(?shim_name, ?instance, sym=?self.symbol_table.lookup(shim_name), "generate_foreign_shim");
10196

102-
let loc = self.codegen_span(&self.tcx.def_span(instance.def_id()));
97+
let loc = self.codegen_span_stable(instance.def.span());
10398
let unsupported_check = self.codegen_ffi_unsupported(instance, loc);
10499
Stmt::block(vec![unsupported_check], loc)
105100
}
106101

107102
/// Generate type for the given foreign instance.
108-
fn codegen_ffi_type(&mut self, instance: Instance<'tcx>) -> Type {
109-
let fn_name = self.symbol_name(instance);
110-
let fn_abi = kani_middle::fn_abi(self.tcx, instance);
111-
let loc = self.codegen_span(&self.tcx.def_span(instance.def_id()));
103+
fn codegen_ffi_type(&mut self, instance: Instance) -> Type {
104+
let fn_name = self.symbol_name_stable(instance);
105+
let fn_abi = kani_middle::fn_abi(self.tcx, rustc_internal::internal(instance));
106+
let loc = self.codegen_span_stable(instance.def.span());
112107
let params = fn_abi
113108
.args
114109
.iter()
@@ -137,15 +132,15 @@ impl<'tcx> GotocCtx<'tcx> {
137132
///
138133
/// This will behave like `codegen_unimplemented_stmt` but print a message that includes
139134
/// the name of the function not supported and the calling convention.
140-
fn codegen_ffi_unsupported(&mut self, instance: Instance<'tcx>, loc: Location) -> Stmt {
141-
let fn_name = &self.symbol_name(instance);
135+
fn codegen_ffi_unsupported(&mut self, instance: Instance, loc: Location) -> Stmt {
136+
let fn_name = &self.symbol_name_stable(instance);
142137
debug!(?fn_name, ?loc, "codegen_ffi_unsupported");
143138

144139
// Save this occurrence so we can emit a warning in the compilation report.
145140
let entry = self.unsupported_constructs.entry("foreign function".into()).or_default();
146141
entry.push(loc);
147142

148-
let call_conv = kani_middle::fn_abi(self.tcx, instance).conv;
143+
let call_conv = kani_middle::fn_abi(self.tcx, rustc_internal::internal(instance)).conv;
149144
let msg = format!("call to foreign \"{call_conv:?}\" function `{fn_name}`");
150145
let url = if call_conv == Conv::C {
151146
"https://github.com/model-checking/kani/issues/2423"

kani-compiler/src/codegen_cprover_gotoc/utils/names.rs

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ use crate::codegen_cprover_gotoc::GotocCtx;
77
use cbmc::InternedString;
88
use rustc_hir::def_id::LOCAL_CRATE;
99
use rustc_middle::mir::mono::CodegenUnitNameBuilder;
10-
use rustc_middle::ty::print::with_no_trimmed_paths;
11-
use rustc_middle::ty::{Instance, TyCtxt};
12-
use stable_mir::mir::mono::Instance as InstanceStable;
10+
use rustc_middle::ty::TyCtxt;
11+
use stable_mir::mir::mono::Instance;
1312
use stable_mir::mir::Local;
14-
use tracing::debug;
1513

1614
impl<'tcx> GotocCtx<'tcx> {
1715
/// The full crate name including versioning info
@@ -52,34 +50,11 @@ impl<'tcx> GotocCtx<'tcx> {
5250
format!("{var_name}_init")
5351
}
5452

55-
/// A human readable name in Rust for reference, should not be used as a key.
56-
pub fn readable_instance_name(&self, instance: Instance<'tcx>) -> String {
57-
with_no_trimmed_paths!(self.tcx.def_path_str_with_args(instance.def_id(), instance.args))
58-
}
59-
60-
/// The actual function name used in the symbol table
61-
pub fn symbol_name(&self, instance: Instance<'tcx>) -> String {
62-
let llvm_mangled = self.tcx.symbol_name(instance).name.to_string();
63-
debug!(
64-
"finding function name for instance: {}, debug: {:?}, name: {}, symbol: {}",
65-
instance,
66-
instance,
67-
self.readable_instance_name(instance),
68-
llvm_mangled,
69-
);
70-
71-
let pretty = self.readable_instance_name(instance);
72-
73-
// Make main function a special case in order to support `--function main`
74-
// TODO: Get rid of this: https://github.com/model-checking/kani/issues/2129
75-
if pretty == "main" { pretty } else { llvm_mangled }
76-
}
77-
7853
/// Return the mangled name to be used in the symbol table.
7954
///
8055
/// We special case main function in order to support `--function main`.
8156
// TODO: Get rid of this: https://github.com/model-checking/kani/issues/2129
82-
pub fn symbol_name_stable(&self, instance: InstanceStable) -> String {
57+
pub fn symbol_name_stable(&self, instance: Instance) -> String {
8358
let pretty = instance.name();
8459
if pretty == "main" { pretty } else { instance.mangled_name() }
8560
}

0 commit comments

Comments
 (0)