Skip to content

Commit

Permalink
Some test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
JustusAdam committed Jan 15, 2024
1 parent 22e200d commit 4354a7b
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 18 deletions.
23 changes: 15 additions & 8 deletions crates/flowistry/src/pdg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use rustc_index::IndexVec;
use rustc_middle::{
mir::{
visit::Visitor, AggregateKind, BasicBlock, Body, Location, Operand, Place, PlaceElem,
Rvalue, Statement, StatementKind, Terminator, TerminatorKind, RETURN_PLACE,
Rvalue, Statement, StatementKind, Terminator, TerminatorKind, RETURN_PLACE
},
ty::{GenericArg, GenericArgsRef, List, ParamEnv, TyCtxt, TyKind},
};
Expand Down Expand Up @@ -857,15 +857,22 @@ impl<'tcx> GraphConstructor<'tcx> {

if self.params.false_call_edges {
let start_domain = &mut domains[0_usize.into()];
// TODO, actually this should be the objects behind any mutable pointer in args
// TODO, actually should traverse all of the types fields
for arg in self.body.args_iter() {
let place = arg.into();
let ty = place.ty(&self.body);
if !ty.ty.is_mutable_ptr() {
continue;
let place = Place::from(arg);
start_domain.last_mutation
.entry(place)
.or_default()
.insert(RichLocation::Start);
for child in self.place_info.children(place).iter().copied().chain(Some(place)) {
let ty = child.ty(self.body.as_ref(), self.tcx);
if !ty.ty.is_mutable_ptr() {
continue;
}
let target = child.project_deeper(&[PlaceElem::Deref], self.tcx);
let initial = start_domain.last_mutation.entry(target).or_default();
initial.insert(RichLocation::Start);
}
let initial = start_domain.last_mutation.entry(arg.into()).or_default();
initial.insert(RichLocation::Start);
}
}

Expand Down
71 changes: 61 additions & 10 deletions crates/flowistry/tests/pdg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ fn main() {
#[test]
fn false_call_edges() {
let input = r#"
fn does_not_mutate(x: &mut i32) {}
fn does_not_mutate(x2: &mut i32) {}
fn main() {
let mut x = 0;
Expand All @@ -521,22 +521,73 @@ fn main() {
let def_id = get_main(tcx);
let params = PdgParams::new(tcx, def_id);

let without_edges = flowistry::pdg::compute_pdg(params.clone());
assert!(!connects(
tcx,
&without_edges,
"x",
"y",
Some("does_not_mutate")
));
// let without_edges = flowistry::pdg::compute_pdg(params.clone());
// assert!(!connects(
// tcx,
// &without_edges,
// "x",
// "y",
// None
// ));

let with_edges = flowistry::pdg::compute_pdg(params.with_false_call_edges());
assert!(connects(
tcx,
&with_edges,
"x",
"*x2",
None
));
assert!(connects(
tcx,
&with_edges,
"*x2",
"y",
Some("does_not_mutate")
None
));
})
}

#[test]
fn false_call_edges_2() {
let input = r#"
struct UserData {
pub data: Vec<i64>,
}
fn get_user_data() -> UserData {
return UserData {
data: vec![1, 2, 3],
};
}
fn send_user_data(user_data: &UserData) {}
fn modify_vec(v: &mut [i64]) {}
fn main() {
let ref mut p = get_user_data();
modify_vec(&mut p.data);
send_user_data(p);
}
"#;

let _ = env_logger::try_init();
flowistry::test_utils::compile(input, move |tcx| {
let def_id = get_main(tcx);
let params = PdgParams::new(tcx, def_id);

let ref with_edges = flowistry::pdg::compute_pdg(params.with_false_call_edges());

assert!(connects(
tcx,
with_edges,
"RETURN.data",
"*v",
None,
));
assert!(connects(
tcx,
with_edges,
"*v",
"user_data",
None,
));
});
}

0 comments on commit 4354a7b

Please sign in to comment.