Skip to content

Commit 4633223

Browse files
committed
feat: define and apply CallGraph::recursive_callees
1 parent 7893118 commit 4633223

File tree

3 files changed

+45
-34
lines changed

3 files changed

+45
-34
lines changed

src/functions/kani/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
mod coercion;
22
mod reachability;
33

4-
pub use reachability::collect_reachable_items;
4+
pub use reachability::{CallGraph, collect_reachable_items};

src/functions/kani/reachability.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
extern crate rustc_data_structures;
2121
extern crate rustc_session;
2222

23+
use super::coercion;
24+
use indexmap::IndexSet;
2325
use rustc_data_structures::fingerprint::Fingerprint;
2426
use rustc_data_structures::fx::FxHashSet;
2527
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -42,8 +44,6 @@ use std::{
4244
io::{BufWriter, Write},
4345
};
4446

45-
use super::coercion;
46-
4747
/// Collect all reachable items starting from the given starting points.
4848
pub fn collect_reachable_items(
4949
tcx: TyCtxt,
@@ -68,15 +68,6 @@ pub fn collect_reachable_items(
6868
// order of the errors and warnings is stable.
6969
let mut sorted_items: Vec<_> = collector.collected.into_iter().collect();
7070
sorted_items.sort_by_cached_key(|item| to_fingerprint(tcx, item));
71-
// print collected fn names
72-
let item_names: Vec<_> = sorted_items
73-
.iter()
74-
.filter_map(|item| match item {
75-
MonoItem::Fn(f) => Some(f.name()),
76-
_ => None,
77-
})
78-
.collect();
79-
dbg!(item_names);
8071
(sorted_items, collector.call_graph)
8172
}
8273

@@ -585,6 +576,25 @@ struct Node(pub MonoItem);
585576
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
586577
struct CollectedNode(pub CollectedItem);
587578

579+
impl CallGraph {
580+
pub fn recursive_callees(&self, item: &MonoItem, callees: &mut IndexSet<Instance>) {
581+
let key = &Node(item.clone());
582+
let nodes = self.edges.get(key).unwrap_or_else(|| panic!("No {item:?} in the call graph."));
583+
584+
for node in nodes {
585+
let item = &node.0.item;
586+
match item {
587+
MonoItem::Fn(inst) => _ = callees.insert(*inst),
588+
// TODO: only consider functions items.
589+
// Functions may be in statics, but need testing to comfirm.
590+
MonoItem::Static(_) => (),
591+
_ => continue,
592+
}
593+
self.recursive_callees(item, callees);
594+
}
595+
}
596+
}
597+
588598
impl CallGraph {
589599
/// Add a new node into a graph.
590600
fn add_node(&mut self, item: MonoItem) {

src/functions/mod.rs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use indexmap::IndexSet;
2-
use kani::collect_reachable_items;
2+
use kani::{CallGraph, collect_reachable_items};
33
use rustc_middle::ty::TyCtxt;
44
use rustc_smir::rustc_internal::internal;
55
use rustc_span::{Span, source_map::SourceMap};
66
use serde::Serialize;
77
use stable_mir::{
8-
CrateDef, CrateItem, DefId, ItemKind,
8+
CrateDef, DefId,
99
mir::mono::{Instance, MonoItem},
1010
ty::{FnDef, RigidTy, Ty, TyKind},
1111
};
@@ -17,7 +17,6 @@ pub fn analyze(tcx: TyCtxt, src_map: &SourceMap) -> Vec<Function> {
1717
let local_items = stable_mir::all_local_items();
1818
let cap = local_items.len();
1919

20-
let mut outputs = Vec::with_capacity(cap);
2120
let mut entries = Vec::with_capacity(cap);
2221

2322
for item in local_items {
@@ -29,7 +28,7 @@ pub fn analyze(tcx: TyCtxt, src_map: &SourceMap) -> Vec<Function> {
2928

3029
let (mono_items, callgraph) = collect_reachable_items(tcx, &entries);
3130

32-
outputs
31+
mono_items.iter().filter_map(|item| Function::new(item, &callgraph, tcx, src_map)).collect()
3332
}
3433

3534
/// A Rust funtion with its file source, attributes, and raw function content.
@@ -48,37 +47,39 @@ pub struct Function {
4847
}
4948

5049
impl Function {
51-
pub fn new(item: CrateItem, tcx: TyCtxt, src_map: &SourceMap) -> Option<Self> {
52-
if !matches!(item.kind(), ItemKind::Fn) {
53-
// skip non fn items
50+
pub fn new(
51+
item: &MonoItem,
52+
callgraph: &CallGraph,
53+
tcx: TyCtxt,
54+
src_map: &SourceMap,
55+
) -> Option<Self> {
56+
// skip non fn items
57+
let &MonoItem::Fn(inst) = item else {
5458
return None;
55-
}
56-
// item.emit_mir(&mut std::io::stdout()).unwrap(); // MIR body
57-
let inst = Instance::try_from(item).inspect_err(|err| error!(?err)).ok()?;
59+
};
60+
5861
let fn_def = ty_to_fndef(inst.ty())?;
59-
let file = item.span().get_filename();
62+
let inst_def = inst.def;
63+
let span = inst_def.span();
64+
65+
let file = span.get_filename();
6066
let body = fn_def.body()?;
6167

6268
let mut callees = IndexSet::new();
63-
// retrieve direct calls
64-
callees.extend(callees::calls_in_body(&body));
65-
// recursive calls
66-
let direct_calls: Vec<_> = callees.iter().copied().collect();
67-
for call in direct_calls {
68-
callees::recursive_callees(call, &mut callees);
69-
}
70-
let callees = callees.into_iter().map(|x| format!("{x:?}")).collect();
69+
callgraph.recursive_callees(item, &mut callees);
70+
let callees = callees.into_iter().map(|x| format!("{:?}", x.def.def_id())).collect();
7171

7272
let func = source_code_with(body.span, tcx, src_map);
73-
info!(" - {:?} ({:?}): {func}", item.name(), item.span());
73+
info!(" - {:?} ({span:?}): {func}", inst_def.name());
7474

7575
// FIXME: kanitool and some other proc-macors attributes are generated by parsing,
7676
// and these generated attrs share with span of hand-written attrs in source code.
7777
// As a result, get_all_attributes through source span will emit duplicated attrs.
7878
// Need to fix this in the future, by analyzing Symbols of these attrs.
79-
let attrs = get_all_attributes(item.def_id(), tcx, src_map);
79+
// let attrs = get_all_attributes(inst_def.def_id(), tcx, src_map);
80+
let attrs = vec![];
8081

81-
// TODO: kanitool kind: proof, proof_for_contract, contract, ...
82+
// TODO: filter in kanitool kind: proof, proof_for_contract, contract, ...
8283

8384
Some(Function { file, attrs, func, callees })
8485
}

0 commit comments

Comments
 (0)