Skip to content

Commit 55b1ea8

Browse files
authored
Merge pull request #9 from os-checker/filter-functions
Feat: Filter in functions annotated by kani
2 parents ad8f820 + 0fe5f82 commit 55b1ea8

File tree

5 files changed

+91
-8901
lines changed

5 files changed

+91
-8901
lines changed

src/functions/callees.rs

Lines changed: 0 additions & 56 deletions
This file was deleted.

src/functions/mod.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@ use kani::{CallGraph, KANI_TOOL_ATTRS, collect_reachable_items};
33
use rustc_middle::ty::TyCtxt;
44
use rustc_smir::rustc_internal::internal;
55
use rustc_span::{Span, source_map::SourceMap};
6-
use serde::Serialize;
76
use stable_mir::{
8-
CrateDef,
7+
CrateDef, DefId,
8+
crate_def::Attribute,
99
mir::mono::{Instance, MonoItem},
1010
ty::{FnDef, RigidTy, Ty, TyKind},
1111
};
1212

13-
mod callees;
1413
mod kani;
14+
mod serialization;
15+
pub use serialization::SerFunction;
1516

16-
pub fn analyze(tcx: TyCtxt, src_map: &SourceMap) -> Vec<Function> {
17+
pub fn analyze(tcx: TyCtxt, src_map: &SourceMap) -> Vec<SerFunction> {
1718
let local_items = stable_mir::all_local_items();
1819
let cap = local_items.len();
1920

@@ -28,22 +29,29 @@ pub fn analyze(tcx: TyCtxt, src_map: &SourceMap) -> Vec<Function> {
2829

2930
let (mono_items, callgraph) = collect_reachable_items(tcx, &entries);
3031

31-
mono_items.iter().filter_map(|item| Function::new(item, &callgraph, tcx, src_map)).collect()
32+
// Filter out non kanitool functions.
33+
mono_items
34+
.iter()
35+
.filter_map(|item| Function::new(item, &callgraph, tcx, src_map, |x| !x.attrs.is_empty()))
36+
.map(SerFunction::new)
37+
.collect()
3238
}
3339

3440
/// A Rust funtion with its file source, attributes, and raw function content.
35-
#[derive(Debug, Default, Serialize)]
41+
#[derive(Debug)]
3642
pub struct Function {
43+
/// DefId in stable_mir.
44+
def_id: DefId,
3745
/// Every funtion must be declared in a specific file, even for those
3846
/// generated by macros.
3947
file: String,
4048
/// Attributes are attached the function, but it seems that attributes
4149
/// and function must be separated to query.
42-
attrs: Vec<String>,
50+
attrs: Vec<Attribute>,
4351
/// Raw function string, including name, signature, and body.
4452
func: String,
4553
/// Recursive fnction calls inside the body.
46-
callees: Vec<String>,
54+
callees: IndexSet<Instance>,
4755
}
4856

4957
impl Function {
@@ -52,34 +60,33 @@ impl Function {
5260
callgraph: &CallGraph,
5361
tcx: TyCtxt,
5462
src_map: &SourceMap,
63+
filter: impl FnOnce(&Self) -> bool,
5564
) -> Option<Self> {
5665
// skip non fn items
5766
let &MonoItem::Fn(inst) = item else {
5867
return None;
5968
};
6069

61-
let fn_def = ty_to_fndef(inst.ty())?;
6270
let inst_def = inst.def;
63-
let span = inst_def.span();
6471

72+
// Only need kanitool attrs: proof, proof_for_contract, contract, ...
73+
let attrs = KANI_TOOL_ATTRS.iter().flat_map(|v| inst_def.tool_attrs(v)).collect();
74+
75+
let span = inst_def.span();
6576
let file = span.get_filename();
77+
78+
let fn_def = ty_to_fndef(inst.ty())?;
6679
let body = fn_def.body()?;
6780

6881
let mut callees = IndexSet::new();
6982
callgraph.recursive_callees(item, &mut callees);
70-
let callees = callees.into_iter().map(|x| format!("{:?}", x.def.def_id())).collect();
7183

7284
let func = source_code_with(body.span, tcx, src_map);
7385
info!(" - {:?} ({span:?}): {func}", inst_def.name());
7486

75-
// Only need kanitool attrs: proof, proof_for_contract, contract, ...
76-
let attrs = KANI_TOOL_ATTRS
77-
.iter()
78-
.flat_map(|v| inst_def.tool_attrs(v))
79-
.map(|attr| attr.as_str().to_owned())
80-
.collect();
81-
82-
Some(Function { file, attrs, func, callees })
87+
let def_id = inst_def.def_id();
88+
let this = Function { def_id, file, attrs, func, callees };
89+
filter(&this).then_some(this)
8390
}
8491
}
8592

src/functions/serialization.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use serde::Serialize;
2+
use stable_mir::{CrateDef, DefId};
3+
4+
/// A Rust funtion with its file source, attributes, and raw function content.
5+
#[derive(Debug, Serialize)]
6+
pub struct SerFunction {
7+
/// DefId in stable_mir.
8+
pub def_id: String,
9+
/// Every funtion must be declared in a specific file, even for those
10+
/// generated by macros.
11+
pub file: String,
12+
/// Attributes are attached the function, but it seems that attributes
13+
/// and function must be separated to query.
14+
pub attrs: Vec<String>,
15+
/// Raw function string, including name, signature, and body.
16+
pub func: String,
17+
/// Recursive fnction calls inside the body.
18+
pub callees: Vec<String>,
19+
}
20+
21+
impl SerFunction {
22+
pub fn new(fun: super::Function) -> Self {
23+
SerFunction {
24+
def_id: format_def_id(&fun.def_id),
25+
file: fun.file,
26+
attrs: fun.attrs.iter().map(|a| a.as_str().to_owned()).collect(),
27+
func: fun.func,
28+
callees: fun.callees.into_iter().map(|x| format_def_id(&x.def.def_id())).collect(),
29+
}
30+
}
31+
}
32+
33+
fn format_def_id(def_id: &DefId) -> String {
34+
format!("{def_id:?}")
35+
}

0 commit comments

Comments
 (0)